Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/964073/?format=api
{ "id": 964073, "url": "http://patchwork.ozlabs.org/api/patches/964073/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/20180830185352.3369-14-logang@deltatee.com/", "project": { "id": 28, "url": "http://patchwork.ozlabs.org/api/projects/28/?format=api", "name": "Linux PCI development", "link_name": "linux-pci", "list_id": "linux-pci.vger.kernel.org", "list_email": "linux-pci@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20180830185352.3369-14-logang@deltatee.com>", "list_archive_url": null, "date": "2018-08-30T18:53:52", "name": "[v5,13/13] nvmet: Optionally use PCI P2P memory", "commit_ref": null, "pull_url": null, "state": "changes-requested", "archived": false, "hash": "a16d857feb941a4f7eb0b53982b8ac12c739ee6d", "submitter": { "id": 70191, "url": "http://patchwork.ozlabs.org/api/people/70191/?format=api", "name": "Logan Gunthorpe", "email": "logang@deltatee.com" }, "delegate": { "id": 6763, "url": "http://patchwork.ozlabs.org/api/users/6763/?format=api", "username": "bhelgaas", "first_name": "Bjorn", "last_name": "Helgaas", "email": "bhelgaas@google.com" }, "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/20180830185352.3369-14-logang@deltatee.com/mbox/", "series": [ { "id": 63352, "url": "http://patchwork.ozlabs.org/api/series/63352/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/list/?series=63352", "date": "2018-08-30T18:53:41", "name": "Copy Offload in NVMe Fabrics with P2P PCI Memory", "version": 5, "mbox": "http://patchwork.ozlabs.org/series/63352/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/964073/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/964073/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<linux-pci-owner@vger.kernel.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=linux-pci-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org; dmarc=none (p=none dis=none)\n\theader.from=deltatee.com" ], "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 421WrS3CPbz9s0n\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 31 Aug 2018 04:54:48 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1727597AbeH3W6O (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n\tThu, 30 Aug 2018 18:58:14 -0400", "from ale.deltatee.com ([207.54.116.67]:40098 \"EHLO\n\tale.deltatee.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1727339AbeH3W5m (ORCPT <rfc822;linux-pci@vger.kernel.org>);\n\tThu, 30 Aug 2018 18:57:42 -0400", "from cgy1-donard.priv.deltatee.com ([172.16.1.31])\n\tby ale.deltatee.com with esmtps\n\t(TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89)\n\t(envelope-from <gunthorp@deltatee.com>)\n\tid 1fvS4u-0006Os-Pd; Thu, 30 Aug 2018 12:54:07 -0600", "from gunthorp by cgy1-donard.priv.deltatee.com with local (Exim\n\t4.89) (envelope-from <gunthorp@deltatee.com>)\n\tid 1fvS4p-0000tr-De; Thu, 30 Aug 2018 12:53:55 -0600" ], "From": "Logan Gunthorpe <logang@deltatee.com>", "To": "linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,\n\tlinux-nvme@lists.infradead.org, linux-rdma@vger.kernel.org,\n\tlinux-nvdimm@lists.01.org, linux-block@vger.kernel.org", "Cc": "Stephen Bates <sbates@raithlin.com>, Christoph Hellwig <hch@lst.de>,\n\tKeith Busch <keith.busch@intel.com>, Sagi Grimberg <sagi@grimberg.me>,\n\tBjorn Helgaas <bhelgaas@google.com>, Jason Gunthorpe <jgg@mellanox.com>, \n\tMax Gurtovoy <maxg@mellanox.com>,\n\tDan Williams <dan.j.williams@intel.com>, =?utf-8?b?SsOpcsO0bWUgR2xp?=\n\t=?utf-8?q?sse?= <jglisse@redhat.com>,\n\tBenjamin Herrenschmidt <benh@kernel.crashing.org>, Alex Williamson\n\t<alex.williamson@redhat.com>, =?utf-8?q?Christian_K=C3=B6nig?=\n\t<christian.koenig@amd.com>, Logan Gunthorpe <logang@deltatee.com>,\n\tSteve Wise <swise@opengridcomputing.com>", "Date": "Thu, 30 Aug 2018 12:53:52 -0600", "Message-Id": "<20180830185352.3369-14-logang@deltatee.com>", "X-Mailer": "git-send-email 2.11.0", "In-Reply-To": "<20180830185352.3369-1-logang@deltatee.com>", "References": "<20180830185352.3369-1-logang@deltatee.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "X-SA-Exim-Connect-IP": "172.16.1.31", "X-SA-Exim-Rcpt-To": "linux-nvme@lists.infradead.org, linux-nvdimm@lists.01.org,\n\tlinux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,\n\tlinux-rdma@vger.kernel.org, linux-block@vger.kernel.org,\n\tsbates@raithlin.com, hch@lst.de, sagi@grimberg.me,\n\tbhelgaas@google.com, jgg@mellanox.com, maxg@mellanox.com,\n\tkeith.busch@intel.com, dan.j.williams@intel.com,\n\tbenh@kernel.crashing.org, jglisse@redhat.com,\n\talex.williamson@redhat.com, christian.koenig@amd.com,\n\tlogang@deltatee.com, swise@opengridcomputing.com", "X-SA-Exim-Mail-From": "gunthorp@deltatee.com", "X-Spam-Checker-Version": "SpamAssassin 3.4.1 (2015-04-28) on ale.deltatee.com", "X-Spam-Level": "", "X-Spam-Status": "No, score=-8.7 required=5.0 tests=ALL_TRUSTED,BAYES_00,\n\tGREYLIST_ISWHITE,\n\tMYRULES_FREE autolearn=ham autolearn_force=no version=3.4.1", "Subject": "[PATCH v5 13/13] nvmet: Optionally use PCI P2P memory", "X-SA-Exim-Version": "4.2.1 (built Tue, 02 Aug 2016 21:08:31 +0000)", "X-SA-Exim-Scanned": "Yes (on ale.deltatee.com)", "Sender": "linux-pci-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<linux-pci.vger.kernel.org>", "X-Mailing-List": "linux-pci@vger.kernel.org" }, "content": "We create a configfs attribute in each nvme-fabrics target port to\nenable p2p memory use. When enabled, the port will only then use the\np2p memory if a p2p memory device can be found which is behind the\nsame switch hierarchy as the RDMA port and all the block devices in\nuse. If the user enabled it and no devices are found, then the system\nwill silently fall back on using regular memory.\n\nIf appropriate, that port will allocate memory for the RDMA buffers\nfor queues from the p2pmem device falling back to system memory should\nanything fail.\n\nIdeally, we'd want to use an NVME CMB buffer as p2p memory. This would\nsave an extra PCI transfer as the NVME card could just take the data\nout of it's own memory. However, at this time, only a limited number\nof cards with CMB buffers seem to be available.\n\nSigned-off-by: Stephen Bates <sbates@raithlin.com>\nSigned-off-by: Steve Wise <swise@opengridcomputing.com>\n[hch: partial rewrite of the initial code]\nSigned-off-by: Christoph Hellwig <hch@lst.de>\nSigned-off-by: Logan Gunthorpe <logang@deltatee.com>\n---\n drivers/nvme/target/configfs.c | 36 +++++++++++\n drivers/nvme/target/core.c | 133 ++++++++++++++++++++++++++++++++++++++++-\n drivers/nvme/target/nvmet.h | 13 ++++\n drivers/nvme/target/rdma.c | 2 +\n 4 files changed, 183 insertions(+), 1 deletion(-)", "diff": "diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c\nindex b37a8e3e3f80..0dfb0e0c3d21 100644\n--- a/drivers/nvme/target/configfs.c\n+++ b/drivers/nvme/target/configfs.c\n@@ -17,6 +17,8 @@\n #include <linux/slab.h>\n #include <linux/stat.h>\n #include <linux/ctype.h>\n+#include <linux/pci.h>\n+#include <linux/pci-p2pdma.h>\n \n #include \"nvmet.h\"\n \n@@ -1094,6 +1096,37 @@ static void nvmet_port_release(struct config_item *item)\n \tkfree(port);\n }\n \n+#ifdef CONFIG_PCI_P2PDMA\n+static ssize_t nvmet_p2pmem_show(struct config_item *item, char *page)\n+{\n+\tstruct nvmet_port *port = to_nvmet_port(item);\n+\n+\treturn pci_p2pdma_enable_show(page, port->p2p_dev, port->use_p2pmem);\n+}\n+\n+static ssize_t nvmet_p2pmem_store(struct config_item *item,\n+\t\tconst char *page, size_t count)\n+{\n+\tstruct nvmet_port *port = to_nvmet_port(item);\n+\tstruct pci_dev *p2p_dev = NULL;\n+\tbool use_p2pmem;\n+\tint error;\n+\n+\terror = pci_p2pdma_enable_store(page, &p2p_dev, &use_p2pmem);\n+\tif (error)\n+\t\treturn error;\n+\n+\tdown_write(&nvmet_config_sem);\n+\tport->use_p2pmem = use_p2pmem;\n+\tpci_dev_put(port->p2p_dev);\n+\tport->p2p_dev = p2p_dev;\n+\tup_write(&nvmet_config_sem);\n+\n+\treturn count;\n+}\n+CONFIGFS_ATTR(nvmet_, p2pmem);\n+#endif /* CONFIG_PCI_P2PDMA */\n+\n static struct configfs_attribute *nvmet_port_attrs[] = {\n \t&nvmet_attr_addr_adrfam,\n \t&nvmet_attr_addr_treq,\n@@ -1101,6 +1134,9 @@ static struct configfs_attribute *nvmet_port_attrs[] = {\n \t&nvmet_attr_addr_trsvcid,\n \t&nvmet_attr_addr_trtype,\n \t&nvmet_attr_param_inline_data_size,\n+#ifdef CONFIG_PCI_P2PDMA\n+\t&nvmet_attr_p2pmem,\n+#endif\n \tNULL,\n };\n \ndiff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c\nindex 6a1c8d5f552b..8f20b1e26c69 100644\n--- a/drivers/nvme/target/core.c\n+++ b/drivers/nvme/target/core.c\n@@ -15,6 +15,7 @@\n #include <linux/module.h>\n #include <linux/random.h>\n #include <linux/rculist.h>\n+#include <linux/pci-p2pdma.h>\n \n #include \"nvmet.h\"\n \n@@ -365,9 +366,29 @@ static void nvmet_ns_dev_disable(struct nvmet_ns *ns)\n \tnvmet_file_ns_disable(ns);\n }\n \n+static int nvmet_p2pdma_add_client(struct nvmet_ctrl *ctrl,\n+\t\tstruct nvmet_ns *ns)\n+{\n+\tint ret;\n+\n+\tif (!blk_queue_pci_p2pdma(ns->bdev->bd_queue)) {\n+\t\tpr_err(\"peer-to-peer DMA is not supported by %s\\n\",\n+\t\t ns->device_path);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = pci_p2pdma_add_client(&ctrl->p2p_clients, nvmet_ns_dev(ns));\n+\tif (ret)\n+\t\tpr_err(\"failed to add peer-to-peer DMA client %s: %d\\n\",\n+\t\t ns->device_path, ret);\n+\n+\treturn ret;\n+}\n+\n int nvmet_ns_enable(struct nvmet_ns *ns)\n {\n \tstruct nvmet_subsys *subsys = ns->subsys;\n+\tstruct nvmet_ctrl *ctrl;\n \tint ret;\n \n \tmutex_lock(&subsys->lock);\n@@ -389,6 +410,14 @@ int nvmet_ns_enable(struct nvmet_ns *ns)\n \tif (ret)\n \t\tgoto out_dev_put;\n \n+\tlist_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {\n+\t\tif (ctrl->p2p_dev) {\n+\t\t\tret = nvmet_p2pdma_add_client(ctrl, ns);\n+\t\t\tif (ret)\n+\t\t\t\tgoto out_remove_clients;\n+\t\t}\n+\t}\n+\n \tif (ns->nsid > subsys->max_nsid)\n \t\tsubsys->max_nsid = ns->nsid;\n \n@@ -417,6 +446,9 @@ int nvmet_ns_enable(struct nvmet_ns *ns)\n out_unlock:\n \tmutex_unlock(&subsys->lock);\n \treturn ret;\n+out_remove_clients:\n+\tlist_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)\n+\t\tpci_p2pdma_remove_client(&ctrl->p2p_clients, nvmet_ns_dev(ns));\n out_dev_put:\n \tnvmet_ns_dev_disable(ns);\n \tgoto out_unlock;\n@@ -425,6 +457,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)\n void nvmet_ns_disable(struct nvmet_ns *ns)\n {\n \tstruct nvmet_subsys *subsys = ns->subsys;\n+\tstruct nvmet_ctrl *ctrl;\n \n \tmutex_lock(&subsys->lock);\n \tif (!ns->enabled)\n@@ -450,6 +483,12 @@ void nvmet_ns_disable(struct nvmet_ns *ns)\n \tpercpu_ref_exit(&ns->ref);\n \n \tmutex_lock(&subsys->lock);\n+\n+\tlist_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {\n+\t\tpci_p2pdma_remove_client(&ctrl->p2p_clients, nvmet_ns_dev(ns));\n+\t\tnvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, 0, 0);\n+\t}\n+\n \tsubsys->nr_namespaces--;\n \tnvmet_ns_changed(subsys, ns->nsid);\n \tnvmet_ns_dev_disable(ns);\n@@ -727,6 +766,23 @@ EXPORT_SYMBOL_GPL(nvmet_req_execute);\n \n int nvmet_req_alloc_sgl(struct nvmet_req *req, struct nvmet_sq *sq)\n {\n+\tstruct pci_dev *p2p_dev = NULL;\n+\n+\tif (IS_ENABLED(CONFIG_PCI_P2PDMA)) {\n+\t\tif (sq->ctrl)\n+\t\t\tp2p_dev = sq->ctrl->p2p_dev;\n+\n+\t\treq->p2p_dev = NULL;\n+\t\tif (sq->qid && p2p_dev) {\n+\t\t\treq->sg = pci_p2pmem_alloc_sgl(p2p_dev, &req->sg_cnt,\n+\t\t\t\t\t\t req->transfer_len);\n+\t\t\tif (req->sg) {\n+\t\t\t\treq->p2p_dev = p2p_dev;\n+\t\t\t\treturn 0;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n \treq->sg = sgl_alloc(req->transfer_len, GFP_KERNEL, &req->sg_cnt);\n \tif (!req->sg)\n \t\treturn -ENOMEM;\n@@ -737,7 +793,11 @@ EXPORT_SYMBOL_GPL(nvmet_req_alloc_sgl);\n \n void nvmet_req_free_sgl(struct nvmet_req *req)\n {\n-\tsgl_free(req->sg);\n+\tif (req->p2p_dev)\n+\t\tpci_p2pmem_free_sgl(req->p2p_dev, req->sg);\n+\telse\n+\t\tsgl_free(req->sg);\n+\n \treq->sg = NULL;\n \treq->sg_cnt = 0;\n }\n@@ -939,6 +999,74 @@ bool nvmet_host_allowed(struct nvmet_req *req, struct nvmet_subsys *subsys,\n \t\treturn __nvmet_host_allowed(subsys, hostnqn);\n }\n \n+/*\n+ * If allow_p2pmem is set, we will try to use P2P memory for the SGL lists for\n+ * Ι/O commands. This requires the PCI p2p device to be compatible with the\n+ * backing device for every namespace on this controller.\n+ */\n+static void nvmet_setup_p2pmem(struct nvmet_ctrl *ctrl, struct nvmet_req *req)\n+{\n+\tstruct nvmet_ns *ns;\n+\tint ret;\n+\n+\tif (!req->port->use_p2pmem || !req->p2p_client)\n+\t\treturn;\n+\n+\tmutex_lock(&ctrl->subsys->lock);\n+\n+\tret = pci_p2pdma_add_client(&ctrl->p2p_clients, req->p2p_client);\n+\tif (ret) {\n+\t\tpr_err(\"failed adding peer-to-peer DMA client %s: %d\\n\",\n+\t\t dev_name(req->p2p_client), ret);\n+\t\tgoto free_devices;\n+\t}\n+\n+\tlist_for_each_entry_rcu(ns, &ctrl->subsys->namespaces, dev_link) {\n+\t\tret = nvmet_p2pdma_add_client(ctrl, ns);\n+\t\tif (ret)\n+\t\t\tgoto free_devices;\n+\t}\n+\n+\tif (req->port->p2p_dev) {\n+\t\tif (!pci_p2pdma_assign_provider(req->port->p2p_dev,\n+\t\t\t\t\t\t&ctrl->p2p_clients)) {\n+\t\t\tpr_info(\"peer-to-peer memory on %s is not supported\\n\",\n+\t\t\t\tpci_name(req->port->p2p_dev));\n+\t\t\tgoto free_devices;\n+\t\t}\n+\t\tctrl->p2p_dev = pci_dev_get(req->port->p2p_dev);\n+\t} else {\n+\t\tctrl->p2p_dev = pci_p2pmem_find(&ctrl->p2p_clients);\n+\t\tif (!ctrl->p2p_dev) {\n+\t\t\tpr_info(\"no supported peer-to-peer memory devices found\\n\");\n+\t\t\tgoto free_devices;\n+\t\t}\n+\t}\n+\n+\tmutex_unlock(&ctrl->subsys->lock);\n+\n+\tpr_info(\"using peer-to-peer memory on %s\\n\", pci_name(ctrl->p2p_dev));\n+\treturn;\n+\n+free_devices:\n+\tpci_p2pdma_client_list_free(&ctrl->p2p_clients);\n+\tmutex_unlock(&ctrl->subsys->lock);\n+}\n+\n+static void nvmet_release_p2pmem(struct nvmet_ctrl *ctrl)\n+{\n+\tif (!ctrl->p2p_dev)\n+\t\treturn;\n+\n+\tmutex_lock(&ctrl->subsys->lock);\n+\n+\tpci_p2pdma_client_list_free(&ctrl->p2p_clients);\n+\tpci_dev_put(ctrl->p2p_dev);\n+\tctrl->p2p_dev = NULL;\n+\n+\tmutex_unlock(&ctrl->subsys->lock);\n+}\n+\n u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,\n \t\tstruct nvmet_req *req, u32 kato, struct nvmet_ctrl **ctrlp)\n {\n@@ -980,6 +1108,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,\n \n \tINIT_WORK(&ctrl->async_event_work, nvmet_async_event_work);\n \tINIT_LIST_HEAD(&ctrl->async_events);\n+\tINIT_LIST_HEAD(&ctrl->p2p_clients);\n \n \tmemcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE);\n \tmemcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE);\n@@ -1041,6 +1170,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,\n \t\tctrl->kato = DIV_ROUND_UP(kato, 1000);\n \t}\n \tnvmet_start_keep_alive_timer(ctrl);\n+\tnvmet_setup_p2pmem(ctrl, req);\n \n \tmutex_lock(&subsys->lock);\n \tlist_add_tail(&ctrl->subsys_entry, &subsys->ctrls);\n@@ -1079,6 +1209,7 @@ static void nvmet_ctrl_free(struct kref *ref)\n \tflush_work(&ctrl->async_event_work);\n \tcancel_work_sync(&ctrl->fatal_err_work);\n \n+\tnvmet_release_p2pmem(ctrl);\n \tida_simple_remove(&cntlid_ida, ctrl->cntlid);\n \n \tkfree(ctrl->sqs);\ndiff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h\nindex 7d6cb61021e4..297861064dd8 100644\n--- a/drivers/nvme/target/nvmet.h\n+++ b/drivers/nvme/target/nvmet.h\n@@ -84,6 +84,11 @@ static inline struct nvmet_ns *to_nvmet_ns(struct config_item *item)\n \treturn container_of(to_config_group(item), struct nvmet_ns, group);\n }\n \n+static inline struct device *nvmet_ns_dev(struct nvmet_ns *ns)\n+{\n+\treturn disk_to_dev(ns->bdev->bd_disk);\n+}\n+\n struct nvmet_cq {\n \tu16\t\t\tqid;\n \tu16\t\t\tsize;\n@@ -134,6 +139,8 @@ struct nvmet_port {\n \tvoid\t\t\t\t*priv;\n \tbool\t\t\t\tenabled;\n \tint\t\t\t\tinline_data_size;\n+\tbool\t\t\t\tuse_p2pmem;\n+\tstruct pci_dev\t\t\t*p2p_dev;\n };\n \n static inline struct nvmet_port *to_nvmet_port(struct config_item *item)\n@@ -182,6 +189,9 @@ struct nvmet_ctrl {\n \t__le32\t\t\t*changed_ns_list;\n \tu32\t\t\tnr_changed_ns;\n \n+\tstruct pci_dev\t\t*p2p_dev;\n+\tstruct list_head\tp2p_clients;\n+\n \tchar\t\t\tsubsysnqn[NVMF_NQN_FIELD_LEN];\n \tchar\t\t\thostnqn[NVMF_NQN_FIELD_LEN];\n };\n@@ -294,6 +304,9 @@ struct nvmet_req {\n \n \tvoid (*execute)(struct nvmet_req *req);\n \tconst struct nvmet_fabrics_ops *ops;\n+\n+\tstruct pci_dev *p2p_dev;\n+\tstruct device *p2p_client;\n };\n \n extern struct workqueue_struct *buffered_io_wq;\ndiff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c\nindex e148dee72ba5..5c9cb752e2ed 100644\n--- a/drivers/nvme/target/rdma.c\n+++ b/drivers/nvme/target/rdma.c\n@@ -735,6 +735,8 @@ static void nvmet_rdma_handle_command(struct nvmet_rdma_queue *queue,\n \t\tcmd->send_sge.addr, cmd->send_sge.length,\n \t\tDMA_TO_DEVICE);\n \n+\tcmd->req.p2p_client = &queue->dev->device->dev;\n+\n \tif (!nvmet_req_init(&cmd->req, &queue->nvme_cq,\n \t\t\t&queue->nvme_sq, &nvmet_rdma_ops))\n \t\treturn;\n", "prefixes": [ "v5", "13/13" ] }