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 <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1466
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Changpeng Liu 2020-03-25 23:33:07 -04:00 committed by Tomasz Zawadzki
parent c3eac3435a
commit 532ae9527b

View File

@ -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,10 +2160,24 @@ 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) {
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;
}
}
}
return 0;
@ -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;
}