nvme: don't rely on phys_addr retrieved from spdk_malloc()

The phys_addr param in spdk_*malloc() is about to be
deprecated, so use a separate spdk_vtophys() call to
retrieve physical addresses.

This patch also adds error checks against SPDK_VTOPHYS_ERROR.
The error handling paths are already there to account for
spdk_*malloc() failures themselves, so reuse them in case
of vtophys failures.

Change-Id: I377636e66b8c570d013c1bb2021f04bce4e6c0ce
Signed-off-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/416998
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Darek Stojaczyk 2019-03-15 13:24:09 +01:00 committed by Changpeng Liu
parent 8165bf7125
commit 27c42e313f
4 changed files with 39 additions and 13 deletions

View File

@ -202,10 +202,9 @@ nvme_allocate_request_user_copy(struct spdk_nvme_qpair *qpair,
{ {
struct nvme_request *req; struct nvme_request *req;
void *dma_buffer = NULL; void *dma_buffer = NULL;
uint64_t phys_addr;
if (buffer && payload_size) { if (buffer && payload_size) {
dma_buffer = spdk_zmalloc(payload_size, 4096, &phys_addr, dma_buffer = spdk_zmalloc(payload_size, 4096, NULL,
SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA); SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA);
if (!dma_buffer) { if (!dma_buffer) {
return NULL; return NULL;

View File

@ -394,12 +394,11 @@ nvme_ctrlr_construct_intel_support_log_page_list(struct spdk_nvme_ctrlr *ctrlr,
static int nvme_ctrlr_set_intel_support_log_pages(struct spdk_nvme_ctrlr *ctrlr) static int nvme_ctrlr_set_intel_support_log_pages(struct spdk_nvme_ctrlr *ctrlr)
{ {
int rc = 0; int rc = 0;
uint64_t phys_addr = 0;
struct nvme_completion_poll_status status; struct nvme_completion_poll_status status;
struct spdk_nvme_intel_log_page_directory *log_page_directory; struct spdk_nvme_intel_log_page_directory *log_page_directory;
log_page_directory = spdk_zmalloc(sizeof(struct spdk_nvme_intel_log_page_directory), log_page_directory = spdk_zmalloc(sizeof(struct spdk_nvme_intel_log_page_directory),
64, &phys_addr, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA); 64, NULL, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA);
if (log_page_directory == NULL) { if (log_page_directory == NULL) {
SPDK_ERRLOG("could not allocate log_page_directory\n"); SPDK_ERRLOG("could not allocate log_page_directory\n");
return -ENXIO; return -ENXIO;
@ -754,7 +753,7 @@ static int
nvme_ctrlr_set_doorbell_buffer_config(struct spdk_nvme_ctrlr *ctrlr) nvme_ctrlr_set_doorbell_buffer_config(struct spdk_nvme_ctrlr *ctrlr)
{ {
int rc = 0; int rc = 0;
uint64_t prp1, prp2; uint64_t prp1, prp2, len;
if (!ctrlr->cdata.oacs.doorbell_buffer_config) { if (!ctrlr->cdata.oacs.doorbell_buffer_config) {
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_SET_KEEP_ALIVE_TIMEOUT, nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_SET_KEEP_ALIVE_TIMEOUT,
@ -770,18 +769,32 @@ nvme_ctrlr_set_doorbell_buffer_config(struct spdk_nvme_ctrlr *ctrlr)
/* only 1 page size for doorbell buffer */ /* only 1 page size for doorbell buffer */
ctrlr->shadow_doorbell = spdk_dma_zmalloc(ctrlr->page_size, ctrlr->page_size, ctrlr->shadow_doorbell = spdk_dma_zmalloc(ctrlr->page_size, ctrlr->page_size,
&prp1); NULL);
if (ctrlr->shadow_doorbell == NULL) { if (ctrlr->shadow_doorbell == NULL) {
rc = -ENOMEM; rc = -ENOMEM;
goto error; goto error;
} }
ctrlr->eventidx = spdk_dma_zmalloc(ctrlr->page_size, ctrlr->page_size, &prp2); len = ctrlr->page_size;
prp1 = spdk_vtophys(ctrlr->shadow_doorbell, &len);
if (prp1 == SPDK_VTOPHYS_ERROR || len != ctrlr->page_size) {
rc = -EFAULT;
goto error;
}
ctrlr->eventidx = spdk_dma_zmalloc(ctrlr->page_size, ctrlr->page_size, NULL);
if (ctrlr->eventidx == NULL) { if (ctrlr->eventidx == NULL) {
rc = -ENOMEM; rc = -ENOMEM;
goto error; goto error;
} }
len = ctrlr->page_size;
prp2 = spdk_vtophys(ctrlr->eventidx, &len);
if (prp2 == SPDK_VTOPHYS_ERROR || len != ctrlr->page_size) {
rc = -EFAULT;
goto error;
}
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_WAIT_FOR_DB_BUF_CFG, nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_WAIT_FOR_DB_BUF_CFG,
ctrlr->opts.admin_timeout_ms); ctrlr->opts.admin_timeout_ms);
@ -1457,7 +1470,6 @@ nvme_ctrlr_construct_namespaces(struct spdk_nvme_ctrlr *ctrlr)
{ {
int rc = 0; int rc = 0;
uint32_t nn = ctrlr->cdata.nn; uint32_t nn = ctrlr->cdata.nn;
uint64_t phys_addr = 0;
/* ctrlr->num_ns may be 0 (startup) or a different number of namespaces (reset), /* ctrlr->num_ns may be 0 (startup) or a different number of namespaces (reset),
* so check if we need to reallocate. * so check if we need to reallocate.
@ -1470,15 +1482,16 @@ nvme_ctrlr_construct_namespaces(struct spdk_nvme_ctrlr *ctrlr)
return 0; return 0;
} }
ctrlr->ns = spdk_zmalloc(nn * sizeof(struct spdk_nvme_ns), 64, ctrlr->ns = spdk_zmalloc(nn * sizeof(struct spdk_nvme_ns), 64, NULL,
&phys_addr, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_SHARE); SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_SHARE);
if (ctrlr->ns == NULL) { if (ctrlr->ns == NULL) {
rc = -ENOMEM; rc = -ENOMEM;
goto fail; goto fail;
} }
ctrlr->nsdata = spdk_zmalloc(nn * sizeof(struct spdk_nvme_ns_data), 64, ctrlr->nsdata = spdk_zmalloc(nn * sizeof(struct spdk_nvme_ns_data), 64,
&phys_addr, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_SHARE | SPDK_MALLOC_DMA); NULL, SPDK_ENV_SOCKET_ID_ANY,
SPDK_MALLOC_SHARE | SPDK_MALLOC_DMA);
if (ctrlr->nsdata == NULL) { if (ctrlr->nsdata == NULL) {
rc = -ENOMEM; rc = -ENOMEM;
goto fail; goto fail;

View File

@ -1012,22 +1012,34 @@ nvme_pcie_qpair_construct(struct spdk_nvme_qpair *qpair)
*/ */
if (pqpair->sq_in_cmb == false) { if (pqpair->sq_in_cmb == false) {
pqpair->cmd = spdk_zmalloc(pqpair->num_entries * sizeof(struct spdk_nvme_cmd), pqpair->cmd = spdk_zmalloc(pqpair->num_entries * sizeof(struct spdk_nvme_cmd),
page_align, &pqpair->cmd_bus_addr, page_align, NULL,
SPDK_ENV_SOCKET_ID_ANY, flags); SPDK_ENV_SOCKET_ID_ANY, flags);
if (pqpair->cmd == NULL) { if (pqpair->cmd == NULL) {
SPDK_ERRLOG("alloc qpair_cmd failed\n"); SPDK_ERRLOG("alloc qpair_cmd failed\n");
return -ENOMEM; return -ENOMEM;
} }
pqpair->cmd_bus_addr = spdk_vtophys(pqpair->cmd, NULL);
if (pqpair->cmd_bus_addr == SPDK_VTOPHYS_ERROR) {
SPDK_ERRLOG("spdk_vtophys(pqpair->cmd) failed\n");
return -EFAULT;
}
} }
pqpair->cpl = spdk_zmalloc(pqpair->num_entries * sizeof(struct spdk_nvme_cpl), pqpair->cpl = spdk_zmalloc(pqpair->num_entries * sizeof(struct spdk_nvme_cpl),
page_align, &pqpair->cpl_bus_addr, page_align, NULL,
SPDK_ENV_SOCKET_ID_ANY, flags); SPDK_ENV_SOCKET_ID_ANY, flags);
if (pqpair->cpl == NULL) { if (pqpair->cpl == NULL) {
SPDK_ERRLOG("alloc qpair_cpl failed\n"); SPDK_ERRLOG("alloc qpair_cpl failed\n");
return -ENOMEM; return -ENOMEM;
} }
pqpair->cpl_bus_addr = spdk_vtophys(pqpair->cpl, NULL);
if (pqpair->cpl_bus_addr == SPDK_VTOPHYS_ERROR) {
SPDK_ERRLOG("spdk_vtophys(pqpair->cpl) failed\n");
return -EFAULT;
}
doorbell_base = &pctrlr->regs->doorbell[0].sq_tdbl; doorbell_base = &pctrlr->regs->doorbell[0].sq_tdbl;
pqpair->sq_tdbl = doorbell_base + (2 * qpair->id + 0) * pctrlr->doorbell_stride_u32; pqpair->sq_tdbl = doorbell_base + (2 * qpair->id + 0) * pctrlr->doorbell_stride_u32;
pqpair->cq_hdbl = doorbell_base + (2 * qpair->id + 1) * pctrlr->doorbell_stride_u32; pqpair->cq_hdbl = doorbell_base + (2 * qpair->id + 1) * pctrlr->doorbell_stride_u32;

View File

@ -153,6 +153,8 @@ spdk_dma_realloc(void *buf, size_t size, size_t align, uint64_t *phys_addr)
void void
spdk_free(void *buf) spdk_free(void *buf)
{ {
/* fix for false-positives in *certain* static analysis tools. */
assert((uintptr_t)buf != UINTPTR_MAX);
free(buf); free(buf);
} }