From: Nitesh Shetty <nj.shetty@samsung.com>
To: Jens Axboe <axboe@kernel.dk>, Jonathan Corbet <corbet@lwn.net>,
Alasdair Kergon <agk@redhat.com>,
Mike Snitzer <snitzer@kernel.org>,
Mikulas Patocka <mpatocka@redhat.com>,
Keith Busch <kbusch@kernel.org>, Christoph Hellwig <hch@lst.de>,
Sagi Grimberg <sagi@grimberg.me>,
Chaitanya Kulkarni <kch@nvidia.com>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>
Cc: martin.petersen@oracle.com, bvanassche@acm.org,
david@fromorbit.com, hare@suse.de,
damien.lemoal@opensource.wdc.com, anuj20.g@samsung.com,
joshi.k@samsung.com, nitheshshetty@gmail.com,
gost.dev@samsung.com, "Nitesh Shetty" <nj.shetty@samsung.com>,
"Javier González" <javier.gonz@samsung.com>,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, dm-devel@lists.linux.dev,
linux-nvme@lists.infradead.org, linux-fsdevel@vger.kernel.org
Subject: [PATCH v20 07/12] nvme: add copy offload support
Date: Mon, 20 May 2024 15:50:20 +0530 [thread overview]
Message-ID: <20240520102033.9361-8-nj.shetty@samsung.com> (raw)
In-Reply-To: <20240520102033.9361-1-nj.shetty@samsung.com>
Current design only supports single source range.
We receive a request with REQ_OP_COPY_DST.
Parse this request which consists of dst(1st) and src(2nd) bios.
Form a copy command (TP 4065)
trace event support for nvme_copy_cmd.
Set the device copy limits to queue limits.
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Kanchan Joshi <joshi.k@samsung.com>
Signed-off-by: Nitesh Shetty <nj.shetty@samsung.com>
Signed-off-by: Javier González <javier.gonz@samsung.com>
Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
---
drivers/nvme/host/constants.c | 1 +
drivers/nvme/host/core.c | 81 ++++++++++++++++++++++++++++++++++-
drivers/nvme/host/trace.c | 19 ++++++++
include/linux/blkdev.h | 1 +
include/linux/nvme.h | 43 +++++++++++++++++--
5 files changed, 141 insertions(+), 4 deletions(-)
diff --git a/drivers/nvme/host/constants.c b/drivers/nvme/host/constants.c
index 6f2ebb5fcdb0..01b02e76e070 100644
--- a/drivers/nvme/host/constants.c
+++ b/drivers/nvme/host/constants.c
@@ -19,6 +19,7 @@ static const char * const nvme_ops[] = {
[nvme_cmd_resv_report] = "Reservation Report",
[nvme_cmd_resv_acquire] = "Reservation Acquire",
[nvme_cmd_resv_release] = "Reservation Release",
+ [nvme_cmd_copy] = "Copy Offload",
[nvme_cmd_zone_mgmt_send] = "Zone Management Send",
[nvme_cmd_zone_mgmt_recv] = "Zone Management Receive",
[nvme_cmd_zone_append] = "Zone Append",
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 954f850f113a..238905f9fff6 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -795,6 +795,66 @@ static inline void nvme_setup_flush(struct nvme_ns *ns,
cmnd->common.nsid = cpu_to_le32(ns->head->ns_id);
}
+static inline blk_status_t nvme_setup_copy_offload(struct nvme_ns *ns,
+ struct request *req,
+ struct nvme_command *cmnd)
+{
+ struct nvme_copy_range *range = NULL;
+ struct bio *bio;
+ u64 dst_lba = 0, src_lba = 0, n_lba = 0;
+ u16 nr_range = 1, control = 0, seg = 1;
+
+ if (blk_rq_nr_phys_segments(req) != BLK_COPY_MAX_SEGMENTS)
+ return BLK_STS_IOERR;
+
+ /*
+ * First bio contains information about destination and last bio
+ * contains information about source.
+ */
+ __rq_for_each_bio(bio, req) {
+ if (seg == blk_rq_nr_phys_segments(req)) {
+ src_lba = nvme_sect_to_lba(ns->head,
+ bio->bi_iter.bi_sector);
+ if (n_lba !=
+ bio->bi_iter.bi_size >> ns->head->lba_shift)
+ return BLK_STS_IOERR;
+ } else {
+ dst_lba = nvme_sect_to_lba(ns->head,
+ bio->bi_iter.bi_sector);
+ n_lba = bio->bi_iter.bi_size >> ns->head->lba_shift;
+ }
+ seg++;
+ }
+
+ if (req->cmd_flags & REQ_FUA)
+ control |= NVME_RW_FUA;
+
+ if (req->cmd_flags & REQ_FAILFAST_DEV)
+ control |= NVME_RW_LR;
+
+ memset(cmnd, 0, sizeof(*cmnd));
+ cmnd->copy.opcode = nvme_cmd_copy;
+ cmnd->copy.nsid = cpu_to_le32(ns->head->ns_id);
+ cmnd->copy.control = cpu_to_le16(control);
+ cmnd->copy.sdlba = cpu_to_le64(dst_lba);
+ cmnd->copy.nr_range = 0;
+
+ range = kmalloc_array(nr_range, sizeof(*range),
+ GFP_ATOMIC | __GFP_NOWARN);
+ if (!range)
+ return BLK_STS_RESOURCE;
+
+ range[0].slba = cpu_to_le64(src_lba);
+ range[0].nlb = cpu_to_le16(n_lba - 1);
+
+ req->special_vec.bv_page = virt_to_page(range);
+ req->special_vec.bv_offset = offset_in_page(range);
+ req->special_vec.bv_len = sizeof(*range) * nr_range;
+ req->rq_flags |= RQF_SPECIAL_PAYLOAD;
+
+ return BLK_STS_OK;
+}
+
static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req,
struct nvme_command *cmnd)
{
@@ -1041,6 +1101,11 @@ blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req)
case REQ_OP_ZONE_APPEND:
ret = nvme_setup_rw(ns, req, cmd, nvme_cmd_zone_append);
break;
+ case REQ_OP_COPY_DST:
+ ret = nvme_setup_copy_offload(ns, req, cmd);
+ break;
+ case REQ_OP_COPY_SRC:
+ return BLK_STS_IOERR;
default:
WARN_ON_ONCE(1);
return BLK_STS_IOERR;
@@ -1218,7 +1283,7 @@ EXPORT_SYMBOL_NS_GPL(nvme_passthru_end, NVME_TARGET_PASSTHRU);
/*
* Recommended frequency for KATO commands per NVMe 1.4 section 7.12.1:
- *
+ *
* The host should send Keep Alive commands at half of the Keep Alive Timeout
* accounting for transport roundtrip times [..].
*/
@@ -1802,6 +1867,18 @@ static void nvme_config_discard(struct nvme_ns *ns, struct queue_limits *lim)
lim->max_discard_segments = NVME_DSM_MAX_RANGES;
}
+static void nvme_config_copy(struct nvme_ns *ns, struct nvme_id_ns *id,
+ struct queue_limits *lim)
+{
+ struct nvme_ctrl *ctrl = ns->ctrl;
+
+ if (ctrl->oncs & NVME_CTRL_ONCS_COPY)
+ lim->max_copy_hw_sectors =
+ nvme_lba_to_sect(ns->head, id->mssrl);
+ else
+ lim->max_copy_hw_sectors = 0;
+}
+
static bool nvme_ns_ids_equal(struct nvme_ns_ids *a, struct nvme_ns_ids *b)
{
return uuid_equal(&a->uuid, &b->uuid) &&
@@ -2098,6 +2175,7 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
if (!nvme_update_disk_info(ns, id, &lim))
capacity = 0;
nvme_config_discard(ns, &lim);
+ nvme_config_copy(ns, id, &lim);
if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
ns->head->ids.csi == NVME_CSI_ZNS)
nvme_update_zone_info(ns, &lim, &zi);
@@ -4833,6 +4911,7 @@ static inline void _nvme_check_size(void)
BUILD_BUG_ON(sizeof(struct nvme_download_firmware) != 64);
BUILD_BUG_ON(sizeof(struct nvme_format_cmd) != 64);
BUILD_BUG_ON(sizeof(struct nvme_dsm_cmd) != 64);
+ BUILD_BUG_ON(sizeof(struct nvme_copy_command) != 64);
BUILD_BUG_ON(sizeof(struct nvme_write_zeroes_cmd) != 64);
BUILD_BUG_ON(sizeof(struct nvme_abort_cmd) != 64);
BUILD_BUG_ON(sizeof(struct nvme_get_log_page_command) != 64);
diff --git a/drivers/nvme/host/trace.c b/drivers/nvme/host/trace.c
index 0288315f0050..dfc97fff886b 100644
--- a/drivers/nvme/host/trace.c
+++ b/drivers/nvme/host/trace.c
@@ -153,6 +153,23 @@ static const char *nvme_trace_read_write(struct trace_seq *p, u8 *cdw10)
return ret;
}
+static const char *nvme_trace_copy(struct trace_seq *p, u8 *cdw10)
+{
+ const char *ret = trace_seq_buffer_ptr(p);
+ u64 sdlba = get_unaligned_le64(cdw10);
+ u8 nr_range = get_unaligned_le16(cdw10 + 8);
+ u16 control = get_unaligned_le16(cdw10 + 10);
+ u32 dsmgmt = get_unaligned_le32(cdw10 + 12);
+ u32 reftag = get_unaligned_le32(cdw10 + 16);
+
+ trace_seq_printf(p,
+ "sdlba=%llu, nr_range=%u, ctrl=0x%x, dsmgmt=%u, reftag=%u",
+ sdlba, nr_range, control, dsmgmt, reftag);
+ trace_seq_putc(p, 0);
+
+ return ret;
+}
+
static const char *nvme_trace_dsm(struct trace_seq *p, u8 *cdw10)
{
const char *ret = trace_seq_buffer_ptr(p);
@@ -340,6 +357,8 @@ const char *nvme_trace_parse_nvm_cmd(struct trace_seq *p,
return nvme_trace_resv_rel(p, cdw10);
case nvme_cmd_resv_report:
return nvme_trace_resv_report(p, cdw10);
+ case nvme_cmd_copy:
+ return nvme_trace_copy(p, cdw10);
default:
return nvme_trace_common(p, cdw10);
}
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 8b1edb46880a..1c5974bb23d5 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1287,6 +1287,7 @@ static inline unsigned int bdev_discard_granularity(struct block_device *bdev)
/* maximum copy offload length, this is set to 128MB based on current testing */
#define BLK_COPY_MAX_BYTES (1 << 27)
+#define BLK_COPY_MAX_SEGMENTS 2
static inline unsigned int bdev_max_copy_sectors(struct block_device *bdev)
{
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index 425573202295..5275a0962a02 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -341,7 +341,7 @@ struct nvme_id_ctrl {
__u8 nvscc;
__u8 nwpc;
__le16 acwu;
- __u8 rsvd534[2];
+ __le16 ocfs;
__le32 sgls;
__le32 mnan;
__u8 rsvd544[224];
@@ -369,6 +369,7 @@ enum {
NVME_CTRL_ONCS_WRITE_ZEROES = 1 << 3,
NVME_CTRL_ONCS_RESERVATIONS = 1 << 5,
NVME_CTRL_ONCS_TIMESTAMP = 1 << 6,
+ NVME_CTRL_ONCS_COPY = 1 << 8,
NVME_CTRL_VWC_PRESENT = 1 << 0,
NVME_CTRL_OACS_SEC_SUPP = 1 << 0,
NVME_CTRL_OACS_NS_MNGT_SUPP = 1 << 3,
@@ -418,7 +419,10 @@ struct nvme_id_ns {
__le16 npdg;
__le16 npda;
__le16 nows;
- __u8 rsvd74[18];
+ __le16 mssrl;
+ __le32 mcl;
+ __u8 msrc;
+ __u8 rsvd91[11];
__le32 anagrpid;
__u8 rsvd96[3];
__u8 nsattr;
@@ -830,6 +834,7 @@ enum nvme_opcode {
nvme_cmd_resv_report = 0x0e,
nvme_cmd_resv_acquire = 0x11,
nvme_cmd_resv_release = 0x15,
+ nvme_cmd_copy = 0x19,
nvme_cmd_zone_mgmt_send = 0x79,
nvme_cmd_zone_mgmt_recv = 0x7a,
nvme_cmd_zone_append = 0x7d,
@@ -853,7 +858,8 @@ enum nvme_opcode {
nvme_opcode_name(nvme_cmd_resv_release), \
nvme_opcode_name(nvme_cmd_zone_mgmt_send), \
nvme_opcode_name(nvme_cmd_zone_mgmt_recv), \
- nvme_opcode_name(nvme_cmd_zone_append))
+ nvme_opcode_name(nvme_cmd_zone_append), \
+ nvme_opcode_name(nvme_cmd_copy))
@@ -1030,6 +1036,36 @@ struct nvme_dsm_range {
__le64 slba;
};
+struct nvme_copy_command {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __le32 nsid;
+ __u64 rsvd2;
+ __le64 metadata;
+ union nvme_data_ptr dptr;
+ __le64 sdlba;
+ __u8 nr_range;
+ __u8 rsvd12;
+ __le16 control;
+ __le16 rsvd13;
+ __le16 dspec;
+ __le32 ilbrt;
+ __le16 lbat;
+ __le16 lbatm;
+};
+
+struct nvme_copy_range {
+ __le64 rsvd0;
+ __le64 slba;
+ __le16 nlb;
+ __le16 rsvd18;
+ __le32 rsvd20;
+ __le32 eilbrt;
+ __le16 elbat;
+ __le16 elbatm;
+};
+
struct nvme_write_zeroes_cmd {
__u8 opcode;
__u8 flags;
@@ -1794,6 +1830,7 @@ struct nvme_command {
struct nvme_download_firmware dlfw;
struct nvme_format_cmd format;
struct nvme_dsm_cmd dsm;
+ struct nvme_copy_command copy;
struct nvme_write_zeroes_cmd write_zeroes;
struct nvme_zone_mgmt_send_cmd zms;
struct nvme_zone_mgmt_recv_cmd zmr;
--
2.17.1
next prev parent reply other threads:[~2024-05-20 11:45 UTC|newest]
Thread overview: 86+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20240520102747epcas5p33497a911ca70c991e5da8e22c5d1336b@epcas5p3.samsung.com>
2024-05-20 10:20 ` [PATCH v20 00/12] Implement copy offload support Nitesh Shetty
2024-05-20 10:20 ` [PATCH v20 01/12] block: Introduce queue limits and sysfs for copy-offload support Nitesh Shetty
2024-05-20 14:33 ` Damien Le Moal
2024-05-21 8:15 ` Nitesh Shetty
2024-05-20 22:42 ` Bart Van Assche
2024-05-21 14:25 ` Nitesh Shetty
2024-05-22 17:49 ` Bart Van Assche
2024-05-23 7:05 ` Nitesh Shetty
2024-05-21 6:57 ` Hannes Reinecke
2024-06-01 5:53 ` Christoph Hellwig
2024-06-03 6:43 ` Nitesh Shetty
2024-05-20 10:20 ` [PATCH v20 02/12] Add infrastructure for copy offload in block and request layer Nitesh Shetty
2024-05-20 15:00 ` Damien Le Moal
2024-05-21 10:50 ` Nitesh Shetty
2024-05-20 23:00 ` Bart Van Assche
2024-05-21 11:17 ` Nitesh Shetty
2024-05-22 17:58 ` Bart Van Assche
2024-05-21 7:01 ` Hannes Reinecke
2024-05-24 6:54 ` Nitesh Shetty
[not found] ` <66503bc7.630a0220.56c85.8b9dSMTPIN_ADDED_BROKEN@mx.google.com>
2024-05-24 13:52 ` Bart Van Assche
2024-05-27 8:27 ` Nitesh Shetty
2024-05-28 14:07 ` Bart Van Assche
2024-05-22 18:05 ` Bart Van Assche
2024-05-23 11:34 ` Nitesh Shetty
2024-05-24 20:33 ` Bart Van Assche
2024-05-29 6:17 ` Nitesh Shetty
2024-05-29 7:48 ` Damien Le Moal
2024-05-29 22:41 ` Bart Van Assche
2024-05-30 7:16 ` Nitesh Shetty
[not found] ` <665850bd.050a0220.a5e6b.5b72SMTPIN_ADDED_BROKEN@mx.google.com>
2024-05-30 17:11 ` Bart Van Assche
2024-05-31 10:17 ` Nitesh Shetty
[not found] ` <6659b691.630a0220.90195.d0ebSMTPIN_ADDED_BROKEN@mx.google.com>
2024-05-31 23:45 ` Bart Van Assche
2024-06-01 5:59 ` Christoph Hellwig
2024-06-03 17:12 ` Bart Van Assche
2024-06-04 4:40 ` Christoph Hellwig
2024-06-04 11:44 ` Bart Van Assche
2024-06-05 8:20 ` Christoph Hellwig
2024-06-24 10:44 ` Nitesh Shetty
2024-06-06 7:28 ` Nitesh Shetty
[not found] ` <CGME20240624105121epcas5p3a5a8c73bd5ef19c02e922e5829a4dff0@epcas5p3.samsung.com>
[not found] ` <6679526f.170a0220.9ffd.aefaSMTPIN_ADDED_BROKEN@mx.google.com>
2024-06-24 16:25 ` Bart Van Assche
2024-06-24 21:55 ` Damien Le Moal
2024-06-25 18:18 ` Bart Van Assche
2024-06-25 21:18 ` Damien Le Moal
2024-06-26 5:22 ` Christoph Hellwig
2024-06-28 13:53 ` Bart Van Assche
[not found] ` <66795280.630a0220.f3ccd.b80cSMTPIN_ADDED_BROKEN@mx.google.com>
2024-06-24 22:58 ` Keith Busch
[not found] ` <CGME20240606072827epcas5p285de8d4f3b0f6d3a87f8341414336b42@epcas5p2.samsung.com>
[not found] ` <66618886.630a0220.4d4fc.1c9cSMTPIN_ADDED_BROKEN@mx.google.com>
2024-06-06 16:44 ` Bart Van Assche
2024-06-01 5:57 ` Christoph Hellwig
2024-05-20 10:20 ` [PATCH v20 03/12] block: add copy offload support Nitesh Shetty
2024-06-01 6:16 ` Christoph Hellwig
2024-06-04 10:50 ` Nitesh Shetty
2024-05-20 10:20 ` [PATCH v20 04/12] block: add emulation for copy Nitesh Shetty
2024-05-21 7:06 ` Hannes Reinecke
2024-05-21 11:29 ` Nitesh Shetty
2024-06-01 6:18 ` Christoph Hellwig
2024-05-20 10:20 ` [PATCH v20 05/12] fs/read_write: Enable copy_file_range for block device Nitesh Shetty
2024-05-21 7:07 ` Hannes Reinecke
2024-05-25 23:02 ` Dave Chinner
2024-05-28 5:57 ` Nitesh Shetty
2024-05-20 10:20 ` [PATCH v20 06/12] fs, block: copy_file_range for def_blk_ops for direct " Nitesh Shetty
2024-05-25 23:09 ` Dave Chinner
2024-05-27 8:43 ` Nitesh Shetty
2024-05-20 10:20 ` Nitesh Shetty [this message]
2024-06-01 6:22 ` [PATCH v20 07/12] nvme: add copy offload support Christoph Hellwig
2024-06-03 11:43 ` Nitesh Shetty
2024-05-20 10:20 ` [PATCH v20 08/12] nvmet: add copy command support for bdev and file ns Nitesh Shetty
2024-05-20 10:20 ` [PATCH v20 09/12] dm: Add support for copy offload Nitesh Shetty
2024-05-21 7:11 ` Hannes Reinecke
2024-05-21 14:08 ` Nitesh Shetty
2024-05-22 6:22 ` Hannes Reinecke
2024-05-22 7:10 ` Nitesh Shetty
2024-05-20 10:20 ` [PATCH v20 10/12] dm: Enable copy offload for dm-linear target Nitesh Shetty
2024-05-20 23:25 ` Bart Van Assche
2024-05-21 14:48 ` Nitesh Shetty
2024-05-20 10:20 ` [PATCH v20 11/12] null: Enable trace capability for null block Nitesh Shetty
2024-05-20 23:27 ` Bart Van Assche
2024-06-01 6:23 ` Christoph Hellwig
2024-06-03 11:04 ` Nitesh Shetty
2024-05-20 10:20 ` [PATCH v20 12/12] null_blk: add support for copy offload Nitesh Shetty
2024-05-20 23:42 ` Bart Van Assche
2024-05-21 14:46 ` Nitesh Shetty
2024-05-22 17:52 ` Bart Van Assche
2024-05-23 6:55 ` Nitesh Shetty
2024-05-20 22:54 ` [PATCH v20 00/12] Implement copy offload support Bart Van Assche
2024-06-01 5:47 ` Christoph Hellwig
2024-06-03 10:53 ` Nitesh Shetty
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=20240520102033.9361-8-nj.shetty@samsung.com \
--to=nj.shetty@samsung.com \
--cc=agk@redhat.com \
--cc=anuj20.g@samsung.com \
--cc=axboe@kernel.dk \
--cc=brauner@kernel.org \
--cc=bvanassche@acm.org \
--cc=corbet@lwn.net \
--cc=damien.lemoal@opensource.wdc.com \
--cc=david@fromorbit.com \
--cc=dm-devel@lists.linux.dev \
--cc=gost.dev@samsung.com \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=jack@suse.cz \
--cc=javier.gonz@samsung.com \
--cc=joshi.k@samsung.com \
--cc=kbusch@kernel.org \
--cc=kch@nvidia.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=martin.petersen@oracle.com \
--cc=mpatocka@redhat.com \
--cc=nitheshshetty@gmail.com \
--cc=sagi@grimberg.me \
--cc=snitzer@kernel.org \
--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