[RFC PATCH 1/3] block: add copy offload support
Mikulas Patocka
mpatocka at redhat.com
Wed Feb 2 08:40:30 PST 2022
On Wed, 2 Feb 2022, Keith Busch wrote:
> On Tue, Feb 01, 2022 at 01:32:29PM -0500, Mikulas Patocka wrote:
> > +int blkdev_issue_copy(struct block_device *bdev1, sector_t sector1,
> > + struct block_device *bdev2, sector_t sector2,
> > + sector_t nr_sects, sector_t *copied, gfp_t gfp_mask)
> > +{
> > + struct page *token;
> > + sector_t m;
> > + int r = 0;
> > + struct completion comp;
> > +
> > + *copied = 0;
> > +
> > + m = min(bdev_max_copy_sectors(bdev1), bdev_max_copy_sectors(bdev2));
> > + if (!m)
> > + return -EOPNOTSUPP;
> > + m = min(m, (sector_t)round_down(UINT_MAX, PAGE_SIZE) >> 9);
> > +
> > + if (unlikely(bdev_read_only(bdev2)))
> > + return -EPERM;
> > +
> > + token = alloc_page(gfp_mask);
> > + if (unlikely(!token))
> > + return -ENOMEM;
> > +
> > + while (nr_sects) {
> > + struct bio *read_bio, *write_bio;
> > + sector_t this_step = min(nr_sects, m);
> > +
> > + read_bio = bio_alloc(gfp_mask, 1);
> > + if (unlikely(!read_bio)) {
> > + r = -ENOMEM;
> > + break;
> > + }
> > + bio_set_op_attrs(read_bio, REQ_OP_COPY_READ_TOKEN, REQ_NOMERGE);
> > + bio_set_dev(read_bio, bdev1);
> > + __bio_add_page(read_bio, token, PAGE_SIZE, 0);
>
> You have this "token" payload as driver specific data, but there's no
> check that bdev1 and bdev2 subscribe to the same driver specific format.
>
> I thought we discussed defining something like a "copy domain" that
> establishes which block devices can offload copy operations to/from each
> other, and that should be checked before proceeding with the copy
> operation.
There is nvme_setup_read_token that fills in the token:
memcpy(token->subsys, "nvme", 4);
token->ns = ns;
token->src_sector = bio->bi_iter.bi_sector;
token->sectors = bio->bi_iter.bi_size >> 9;
There is nvme_setup_write_token that checks these values:
if (unlikely(memcmp(token->subsys, "nvme", 4)))
return BLK_STS_NOTSUPP;
if (unlikely(token->ns != ns))
return BLK_STS_NOTSUPP;
So, if we attempt to copy data between the nvme subsystem and the scsi
subsystem, the "subsys" check will fail. If we attempt to copy data
between different nvme namespaces, the "ns" check will fail.
If the nvme standard gets extended with cross-namespace copies, we can
check in nvme_setup_write_token if we can copy between the source and
destination namespace.
Mikulas
More information about the Linux-nvme
mailing list