From: Nitesh Shetty <nj.shetty@samsung.com>
To: unlisted-recipients:; (no To-header on input)
Cc: chaitanyak@nvidia.com, linux-block@vger.kernel.org,
linux-scsi@vger.kernel.org, dm-devel@redhat.com,
linux-nvme@lists.infradead.org, linux-fsdevel@vger.kernel.org,
axboe@kernel.dk, msnitzer@redhat.com, bvanassche@acm.org,
martin.petersen@oracle.com, hare@suse.de, kbusch@kernel.org,
hch@lst.de, Frederick.Knight@netapp.com, osandov@fb.com,
lsf-pc@lists.linux-foundation.org, djwong@kernel.org,
josef@toxicpanda.com, clm@fb.com, dsterba@suse.com,
tytso@mit.edu, jack@suse.com, nitheshshetty@gmail.com,
gost.dev@samsung.com, Nitesh Shetty <nj.shetty@samsung.com>,
Vincent Fu <vincent.fu@samsung.com>,
Arnav Dawn <arnav.dawn@samsung.com>,
Alasdair Kergon <agk@redhat.com>,
Mike Snitzer <snitzer@kernel.org>,
Sagi Grimberg <sagi@grimberg.me>,
James Smart <james.smart@broadcom.com>,
Chaitanya Kulkarni <kch@nvidia.com>,
Damien Le Moal <damien.lemoal@opensource.wdc.com>,
Naohiro Aota <naohiro.aota@wdc.com>,
Johannes Thumshirn <jth@kernel.org>,
Alexander Viro <viro@zeniv.linux.org.uk>,
linux-kernel@vger.kernel.org
Subject: [PATCH v4 04/10] block: add emulation for copy
Date: Tue, 26 Apr 2022 15:42:32 +0530 [thread overview]
Message-ID: <20220426101241.30100-5-nj.shetty@samsung.com> (raw)
In-Reply-To: <20220426101241.30100-1-nj.shetty@samsung.com>
For the devices which does not support copy, copy emulation is
added. Copy-emulation is implemented by reading from source ranges
into memory and writing to the corresponding destination synchronously.
Signed-off-by: Nitesh Shetty <nj.shetty@samsung.com>
Signed-off-by: Vincent Fu <vincent.fu@samsung.com>
Signed-off-by: Arnav Dawn <arnav.dawn@samsung.com>
---
block/blk-lib.c | 128 ++++++++++++++++++++++++++++++++++++++++-
block/blk-map.c | 2 +-
include/linux/blkdev.h | 2 +
3 files changed, 130 insertions(+), 2 deletions(-)
diff --git a/block/blk-lib.c b/block/blk-lib.c
index ba9da2d2f429..58c30a42ea44 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -273,6 +273,65 @@ int blk_copy_offload(struct block_device *src_bdev, int nr_srcs,
return cio_await_completion(cio);
}
+int blk_submit_rw_buf(struct block_device *bdev, void *buf, sector_t buf_len,
+ sector_t sector, unsigned int op, gfp_t gfp_mask)
+{
+ struct request_queue *q = bdev_get_queue(bdev);
+ struct bio *bio, *parent = NULL;
+ sector_t max_hw_len = min_t(unsigned int, queue_max_hw_sectors(q),
+ queue_max_segments(q) << (PAGE_SHIFT - SECTOR_SHIFT)) << SECTOR_SHIFT;
+ sector_t len, remaining;
+ int ret;
+
+ for (remaining = buf_len; remaining > 0; remaining -= len) {
+ len = min_t(int, max_hw_len, remaining);
+retry:
+ bio = bio_map_kern(q, buf, len, gfp_mask);
+ if (IS_ERR(bio)) {
+ len >>= 1;
+ if (len)
+ goto retry;
+ return PTR_ERR(bio);
+ }
+
+ bio->bi_iter.bi_sector = sector >> SECTOR_SHIFT;
+ bio->bi_opf = op;
+ bio_set_dev(bio, bdev);
+ bio->bi_end_io = NULL;
+ bio->bi_private = NULL;
+
+ if (parent) {
+ bio_chain(parent, bio);
+ submit_bio(parent);
+ }
+ parent = bio;
+ sector += len;
+ buf = (char *) buf + len;
+ }
+ ret = submit_bio_wait(bio);
+ bio_put(bio);
+
+ return ret;
+}
+
+static void *blk_alloc_buf(sector_t req_size, sector_t *alloc_size, gfp_t gfp_mask)
+{
+ int min_size = PAGE_SIZE;
+ void *buf;
+
+ while (req_size >= min_size) {
+ buf = kvmalloc(req_size, gfp_mask);
+ if (buf) {
+ *alloc_size = req_size;
+ return buf;
+ }
+ /* retry half the requested size */
+ req_size >>= 1;
+ }
+
+ return NULL;
+}
+
static inline int blk_copy_sanity_check(struct block_device *src_bdev,
struct block_device *dst_bdev, struct range_entry *rlist, int nr)
{
@@ -298,6 +357,68 @@ static inline int blk_copy_sanity_check(struct block_device *src_bdev,
return 0;
}
+/* returns the total copy length still need to be copied */
+static inline sector_t blk_copy_max_range(struct range_entry *rlist, int nr, sector_t *max_len)
+{
+ int i;
+ sector_t len = 0;
+
+ *max_len = 0;
+ for (i = 0; i < nr; i++) {
+ *max_len = max(*max_len, rlist[i].len - rlist[i].comp_len);
+ len += (rlist[i].len - rlist[i].comp_len);
+ }
+
+ return len;
+}
+
+/*
+ * If native copy offload feature is absent, this function tries to emulate,
+ * by copying data from source to a temporary buffer and from buffer to
+ * destination device.
+ */
+static int blk_copy_emulate(struct block_device *src_bdev, int nr,
+ struct range_entry *rlist, struct block_device *dest_bdev, gfp_t gfp_mask)
+{
+ void *buf = NULL;
+ int ret, nr_i = 0;
+ sector_t src, dst, copy_len, buf_len, read_len, copied_len,
+ max_len = 0, remaining = 0, offset = 0;
+
+ copy_len = blk_copy_max_range(rlist, nr, &max_len);
+ buf = blk_alloc_buf(max_len, &buf_len, gfp_mask);
+ if (!buf)
+ return -ENOMEM;
+
+ for (copied_len = 0; copied_len < copy_len; copied_len += read_len) {
+ if (!remaining) {
+ offset = rlist[nr_i].comp_len;
+ src = rlist[nr_i].src + offset;
+ dst = rlist[nr_i].dst + offset;
+ remaining = rlist[nr_i++].len - offset;
+ }
+
+ read_len = min_t(sector_t, remaining, buf_len);
+ if (!read_len)
+ continue;
+ ret = blk_submit_rw_buf(src_bdev, buf, read_len, src, REQ_OP_READ, gfp_mask);
+ if (ret)
+ goto out;
+ src += read_len;
+ remaining -= read_len;
+ ret = blk_submit_rw_buf(dest_bdev, buf, read_len, dst, REQ_OP_WRITE,
+ gfp_mask);
+ if (ret)
+ goto out;
+ else
+ rlist[nr_i - 1].comp_len += read_len;
+ dst += read_len;
+ }
+out:
+ kvfree(buf);
+ return ret;
+}
+
static inline bool blk_check_copy_offload(struct request_queue *src_q,
struct request_queue *dest_q)
{
@@ -325,6 +446,7 @@ int blkdev_issue_copy(struct block_device *src_bdev, int nr,
struct request_queue *src_q = bdev_get_queue(src_bdev);
struct request_queue *dest_q = bdev_get_queue(dest_bdev);
int ret = -EINVAL;
+ bool offload = false;
if (!src_q || !dest_q)
return -ENXIO;
@@ -342,9 +464,13 @@ int blkdev_issue_copy(struct block_device *src_bdev, int nr,
if (ret)
return ret;
- if (blk_check_copy_offload(src_q, dest_q))
+ offload = blk_check_copy_offload(src_q, dest_q);
+ if (offload)
ret = blk_copy_offload(src_bdev, nr, rlist, dest_bdev, gfp_mask);
+ if (ret || !offload)
+ ret = blk_copy_emulate(src_bdev, nr, rlist, dest_bdev, gfp_mask);
+
return ret;
}
EXPORT_SYMBOL_GPL(blkdev_issue_copy);
diff --git a/block/blk-map.c b/block/blk-map.c
index 7ffde64f9019..ca2ad2c21f42 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -340,7 +340,7 @@ static void bio_map_kern_endio(struct bio *bio)
* Map the kernel address into a bio suitable for io to a block
* device. Returns an error pointer in case of error.
*/
-static struct bio *bio_map_kern(struct request_queue *q, void *data,
+struct bio *bio_map_kern(struct request_queue *q, void *data,
unsigned int len, gfp_t gfp_mask)
{
unsigned long kaddr = (unsigned long)data;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index c6cb3fe82ba2..ea1f3c8f8dad 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1121,6 +1121,8 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
sector_t nr_sects, gfp_t gfp_mask, struct bio **biop);
int blkdev_issue_secure_erase(struct block_device *bdev, sector_t sector,
sector_t nr_sects, gfp_t gfp);
+struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len,
+ gfp_t gfp_mask);
int blkdev_issue_copy(struct block_device *src_bdev, int nr_srcs,
struct range_entry *src_rlist, struct block_device *dest_bdev, gfp_t gfp_mask);
--
2.35.1.500.gb896f729e2
next prev parent reply other threads:[~2022-04-26 12:16 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20220426101804epcas5p4a0a325d3ce89e868e4924bbdeeba6d15@epcas5p4.samsung.com>
2022-04-26 10:12 ` [PATCH v4 00/10] Add Copy offload support Nitesh Shetty
[not found] ` <CGME20220426101910epcas5p4fd64f83c6da9bbd891107d158a2743b5@epcas5p4.samsung.com>
2022-04-26 10:12 ` [PATCH v4 01/10] block: Introduce queue limits for copy-offload support Nitesh Shetty
2022-04-27 1:59 ` Damien Le Moal
2022-04-27 10:30 ` Hannes Reinecke
[not found] ` <CGME20220426101921epcas5p341707619b5e836490284a42c92762083@epcas5p3.samsung.com>
2022-04-26 10:12 ` [PATCH v4 02/10] block: Add copy offload support infrastructure Nitesh Shetty
2022-04-27 2:45 ` Damien Le Moal
2022-04-27 15:15 ` Nitesh Shetty
2022-04-27 22:04 ` Damien Le Moal
2022-04-28 8:01 ` Nitesh Shetty
2022-04-27 10:29 ` Hannes Reinecke
2022-04-27 15:48 ` Nitesh Shetty
[not found] ` <CGME20220426101938epcas5p291690dd1f0e931cd9f8139daaf3f9296@epcas5p2.samsung.com>
2022-04-26 10:12 ` [PATCH v4 03/10] block: Introduce a new ioctl for copy Nitesh Shetty
2022-04-27 2:48 ` Damien Le Moal
2022-04-27 13:03 ` Nitesh Shetty
2022-04-27 10:37 ` Hannes Reinecke
[not found] ` <CGME20220426101951epcas5p1f53a2120010607354dc29bf8331f6af8@epcas5p1.samsung.com>
2022-04-26 10:12 ` Nitesh Shetty [this message]
[not found] ` <CGME20220426102001epcas5p4e321347334971d704cb19ffa25f9d0b4@epcas5p4.samsung.com>
2022-04-26 10:12 ` [PATCH v4 05/10] nvme: add copy offload support Nitesh Shetty
[not found] ` <CGME20220426102009epcas5p3e5b1ddfd5d3c7200972cecb139650da6@epcas5p3.samsung.com>
2022-04-26 10:12 ` [PATCH v4 06/10] nvmet: add copy command support for bdev and file ns Nitesh Shetty
[not found] ` <CGME20220426102017epcas5p295d3b62eaa250765e48c767962cbf08b@epcas5p2.samsung.com>
2022-04-26 10:12 ` [PATCH v4 07/10] dm: Add support for copy offload Nitesh Shetty
[not found] ` <CGME20220426102025epcas5p299d9a88c30db8b9a04a05c57dc809ff7@epcas5p2.samsung.com>
2022-04-26 10:12 ` [PATCH v4 08/10] dm: Enable copy offload for dm-linear target Nitesh Shetty
[not found] ` <CGME20220426102033epcas5p137171ff842e8b0a090d2708cfc0e3249@epcas5p1.samsung.com>
2022-04-26 10:12 ` [PATCH v4 09/10] dm kcopyd: use copy offload support Nitesh Shetty
[not found] ` <CGME20220426102042epcas5p201aa0d9143d7bc650ae7858383b69288@epcas5p2.samsung.com>
2022-04-26 10:12 ` [PATCH v4 10/10] fs: add support for copy file range in zonefs Nitesh Shetty
2022-04-27 1:42 ` Damien Le Moal
2022-04-27 1:46 ` [PATCH v4 00/10] Add Copy offload support Damien Le Moal
2022-04-27 15:38 ` Nitesh Shetty
2022-04-27 21:56 ` Damien Le Moal
2022-04-27 2:00 ` Damien Le Moal
2022-04-27 2:19 ` Damien Le Moal
2022-04-27 12:49 ` Nitesh Shetty
2022-04-27 22:05 ` Damien Le Moal
2022-04-28 7:49 ` Nitesh Shetty
2022-04-28 21:37 ` Damien Le Moal
2022-04-29 3:39 ` [dm-devel] " Bart Van Assche
2022-05-02 4:09 ` Dave Chinner
2022-05-02 12:54 ` Damien Le Moal
2022-05-02 23:20 ` Dave Chinner
2022-05-02 12:14 ` [dm-devel] " Damien Le Moal
2022-05-02 12:16 ` Damien Le Moal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220426101241.30100-5-nj.shetty@samsung.com \
--to=nj.shetty@samsung.com \
--cc=Frederick.Knight@netapp.com \
--cc=agk@redhat.com \
--cc=arnav.dawn@samsung.com \
--cc=axboe@kernel.dk \
--cc=bvanassche@acm.org \
--cc=chaitanyak@nvidia.com \
--cc=clm@fb.com \
--cc=damien.lemoal@opensource.wdc.com \
--cc=djwong@kernel.org \
--cc=dm-devel@redhat.com \
--cc=dsterba@suse.com \
--cc=gost.dev@samsung.com \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=jack@suse.com \
--cc=james.smart@broadcom.com \
--cc=josef@toxicpanda.com \
--cc=jth@kernel.org \
--cc=kbusch@kernel.org \
--cc=kch@nvidia.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=linux-scsi@vger.kernel.org \
--cc=lsf-pc@lists.linux-foundation.org \
--cc=martin.petersen@oracle.com \
--cc=msnitzer@redhat.com \
--cc=naohiro.aota@wdc.com \
--cc=nitheshshetty@gmail.com \
--cc=osandov@fb.com \
--cc=sagi@grimberg.me \
--cc=snitzer@kernel.org \
--cc=tytso@mit.edu \
--cc=vincent.fu@samsung.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).