From c29cca539df3bb4176bdf5e61ad8656965971b2c Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Mon, 10 Feb 2020 14:00:04 -0700 Subject: [PATCH] nvme/pcie: Don't allow both sq and data in CMB at same time This is allowed by the specification, but preventing using both of these features simultaneously will make some upcoming patches much simpler. Change-Id: I1abb7d9c02c105a50b1603bfab8eec2025289123 Signed-off-by: Ben Walker Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/782 Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Jim Harris Reviewed-by: Changpeng Liu --- lib/nvme/nvme_pcie.c | 58 ++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/lib/nvme/nvme_pcie.c b/lib/nvme/nvme_pcie.c index ccb15038e..6d7e1d4f1 100644 --- a/lib/nvme/nvme_pcie.c +++ b/lib/nvme/nvme_pcie.c @@ -580,28 +580,6 @@ nvme_pcie_ctrlr_unmap_cmb(struct nvme_pcie_ctrlr *pctrlr) return rc; } -static int -nvme_pcie_ctrlr_alloc_cmb(struct spdk_nvme_ctrlr *ctrlr, uint64_t length, uint64_t aligned, - uint64_t *offset) -{ - struct nvme_pcie_ctrlr *pctrlr = nvme_pcie_ctrlr(ctrlr); - uint64_t round_offset; - - round_offset = pctrlr->cmb.current_offset; - round_offset = (round_offset + (aligned - 1)) & ~(aligned - 1); - - /* CMB may only consume part of the BAR, calculate accordingly */ - if (round_offset + length > pctrlr->cmb.end) { - SPDK_ERRLOG("Tried to allocate past valid CMB range!\n"); - return -1; - } - - *offset = round_offset; - pctrlr->cmb.current_offset = round_offset + length; - - return 0; -} - static void * nvme_pcie_ctrlr_alloc_cmb_io_buffer(struct spdk_nvme_ctrlr *ctrlr, size_t size) { @@ -618,11 +596,21 @@ nvme_pcie_ctrlr_alloc_cmb_io_buffer(struct spdk_nvme_ctrlr *ctrlr, size_t size) return NULL; } - if (nvme_pcie_ctrlr_alloc_cmb(ctrlr, size, 4, &offset) != 0) { - SPDK_DEBUGLOG(SPDK_LOG_NVME, "%zu-byte CMB allocation failed\n", size); + if (ctrlr->opts.use_cmb_sqs) { + SPDK_ERRLOG("CMB is already in use for submission queues.\n"); return NULL; } + offset = (pctrlr->cmb.current_offset + (3)) & ~(3); + + /* CMB may only consume part of the BAR, calculate accordingly */ + if (offset + size > pctrlr->cmb.end) { + SPDK_ERRLOG("Tried to allocate past valid CMB range!\n"); + return NULL; + } + + pctrlr->cmb.current_offset = offset + size; + return pctrlr->cmb.bar_va + offset; } @@ -979,6 +967,28 @@ nvme_pcie_qpair_reset(struct spdk_nvme_qpair *qpair) return 0; } +static int +nvme_pcie_ctrlr_alloc_cmb(struct spdk_nvme_ctrlr *ctrlr, uint64_t length, uint64_t aligned, + uint64_t *offset) +{ + struct nvme_pcie_ctrlr *pctrlr = nvme_pcie_ctrlr(ctrlr); + uint64_t round_offset; + + round_offset = pctrlr->cmb.current_offset; + round_offset = (round_offset + (aligned - 1)) & ~(aligned - 1); + + /* CMB may only consume part of the BAR, calculate accordingly */ + if (round_offset + length > pctrlr->cmb.end) { + SPDK_ERRLOG("Tried to allocate past valid CMB range!\n"); + return -1; + } + + *offset = round_offset; + pctrlr->cmb.current_offset = round_offset + length; + + return 0; +} + static int nvme_pcie_qpair_construct(struct spdk_nvme_qpair *qpair, const struct spdk_nvme_io_qpair_opts *opts)