From 532ae9527b07b1ed9fa5eb6e57d1e4de4d94a172 Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Wed, 25 Mar 2020 23:33:07 -0400 Subject: [PATCH] nvme: enable separate metadata buffer with SGL support If the request contains separate metadata buffer, we should set PSDT 10b when hardware SGL is supported and dword alignment is required. SPDK driver doesn't provide SGL metadata data buffer APIs for now, the separate metadata buffer is alway contiguous, so we can put the metadata buffer into a data block SGL entry. Change-Id: I9ccfce755a3169cd2c9b908e4da76081155d9613 Signed-off-by: Changpeng Liu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1466 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Paul Luse Reviewed-by: Shuhei Matsumoto Reviewed-by: Aleksey Marchuk --- lib/nvme/nvme_pcie.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/nvme/nvme_pcie.c b/lib/nvme/nvme_pcie.c index 6f8f66dbd..348ee2ad7 100644 --- a/lib/nvme/nvme_pcie.c +++ b/lib/nvme/nvme_pcie.c @@ -2149,7 +2149,7 @@ static build_req_fn const g_nvme_pcie_build_req_table[][2] = { static int nvme_pcie_qpair_build_metadata(struct spdk_nvme_qpair *qpair, struct nvme_tracker *tr, - bool dword_aligned) + bool sgl_supported, bool dword_aligned) { void *md_payload; struct nvme_request *req = tr->req; @@ -2160,9 +2160,23 @@ nvme_pcie_qpair_build_metadata(struct spdk_nvme_qpair *qpair, struct nvme_tracke SPDK_ERRLOG("virt_addr %p not dword aligned\n", md_payload); goto exit; } - tr->req->cmd.mptr = spdk_vtophys(md_payload, NULL); - if (tr->req->cmd.mptr == SPDK_VTOPHYS_ERROR) { - goto exit; + + if (sgl_supported && dword_aligned) { + assert(req->cmd.psdt == SPDK_NVME_PSDT_SGL_MPTR_CONTIG); + req->cmd.psdt = SPDK_NVME_PSDT_SGL_MPTR_SGL; + tr->meta_sgl.address = spdk_vtophys(md_payload, NULL); + if (tr->meta_sgl.address == SPDK_VTOPHYS_ERROR) { + goto exit; + } + tr->meta_sgl.unkeyed.type = SPDK_NVME_SGL_TYPE_DATA_BLOCK; + tr->meta_sgl.unkeyed.length = req->md_size; + tr->meta_sgl.unkeyed.subtype = 0; + req->cmd.mptr = tr->prp_sgl_bus_addr - sizeof(struct spdk_nvme_sgl_descriptor); + } else { + req->cmd.mptr = spdk_vtophys(md_payload, NULL); + if (req->cmd.mptr == SPDK_VTOPHYS_ERROR) { + goto exit; + } } } @@ -2219,7 +2233,7 @@ nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_reques goto exit; } - rc = nvme_pcie_qpair_build_metadata(qpair, tr, dword_aligned); + rc = nvme_pcie_qpair_build_metadata(qpair, tr, sgl_supported, dword_aligned); if (rc < 0) { goto exit; }