nvmf/vfio-user: unmap queue pairs when removing memory region

Actually we already do this when removeing a memory region, but
the check for it is too strict, we should unmap queue pairs when
the queue pair is in the memory region.

Change-Id: Ia646a0255e32ecdd0a70537a8011ce622eb59195
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6861
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Changpeng Liu 2021-03-12 21:14:56 +08:00 committed by Tomasz Zawadzki
parent adfec326b6
commit dc03266366

View File

@ -1066,15 +1066,13 @@ memory_region_add_cb(vfu_ctx_t *vfu_ctx, uint64_t iova, uint64_t len, uint32_t p
int i, ret; int i, ret;
assert(endpoint != NULL); assert(endpoint != NULL);
if (endpoint->ctrlr == NULL) { if (endpoint->ctrlr == NULL) {
return; return;
} }
ctrlr = endpoint->ctrlr; ctrlr = endpoint->ctrlr;
SPDK_DEBUGLOG(nvmf_vfio, "%s: map IOVA %#lx-%#lx\n", SPDK_DEBUGLOG(nvmf_vfio, "%s: map IOVA %#lx-%#lx\n",
ctrlr_id(ctrlr), iova, len); ctrlr_id(ctrlr), iova, iova + len);
for (i = 0; i < NVMF_VFIO_USER_DEFAULT_MAX_QPAIRS_PER_CTRLR; i++) { for (i = 0; i < NVMF_VFIO_USER_DEFAULT_MAX_QPAIRS_PER_CTRLR; i++) {
qpair = ctrlr->qp[i]; qpair = ctrlr->qp[i];
@ -1109,7 +1107,6 @@ memory_region_add_cb(vfu_ctx_t *vfu_ctx, uint64_t iova, uint64_t len, uint32_t p
i, cq->prp1, cq->prp1 + cq->size * 16); i, cq->prp1, cq->prp1 + cq->size * 16);
continue; continue;
} }
qpair->state = VFIO_USER_QPAIR_ACTIVE; qpair->state = VFIO_USER_QPAIR_ACTIVE;
} }
} }
@ -1121,27 +1118,28 @@ memory_region_remove_cb(vfu_ctx_t *vfu_ctx, uint64_t iova, uint64_t len)
struct nvmf_vfio_user_endpoint *endpoint = vfu_get_private(vfu_ctx); struct nvmf_vfio_user_endpoint *endpoint = vfu_get_private(vfu_ctx);
struct nvmf_vfio_user_ctrlr *ctrlr; struct nvmf_vfio_user_ctrlr *ctrlr;
struct nvmf_vfio_user_qpair *qpair;
int i; int i;
assert(endpoint != NULL); assert(endpoint != NULL);
if (endpoint->ctrlr == NULL) { if (endpoint->ctrlr == NULL) {
return 0; return 0;
} }
ctrlr = endpoint->ctrlr; ctrlr = endpoint->ctrlr;
SPDK_DEBUGLOG(nvmf_vfio, "%s: unmap IOVA %#lx\n", SPDK_DEBUGLOG(nvmf_vfio, "%s: unmap IOVA %#lx-%#lx\n",
ctrlr_id(ctrlr), iova); ctrlr_id(ctrlr), iova, iova + len);
for (i = 0; i < NVMF_VFIO_USER_DEFAULT_MAX_QPAIRS_PER_CTRLR; i++) { for (i = 0; i < NVMF_VFIO_USER_DEFAULT_MAX_QPAIRS_PER_CTRLR; i++) {
if (ctrlr->qp[i] == NULL) { qpair = ctrlr->qp[i];
if (qpair == NULL) {
continue; continue;
} }
if (ctrlr->qp[i]->cq.sg.dma_addr == iova ||
ctrlr->qp[i]->sq.sg.dma_addr == iova) { if ((qpair->cq.sg.dma_addr >= iova && qpair->cq.sg.dma_addr < iova + len) ||
unmap_qp(ctrlr->qp[i]); (qpair->sq.sg.dma_addr >= iova && qpair->sq.sg.dma_addr < iova + len)) {
ctrlr->qp[i]->state = VFIO_USER_QPAIR_INACTIVE; unmap_qp(qpair);
qpair->state = VFIO_USER_QPAIR_INACTIVE;
} }
} }
@ -1183,12 +1181,14 @@ nvmf_vfio_user_prop_req_rsp(struct nvmf_vfio_user_req *req, void *cb_arg)
SPDK_ERRLOG("%s: failed to map Admin queue\n", ctrlr_id(qpair->ctrlr)); SPDK_ERRLOG("%s: failed to map Admin queue\n", ctrlr_id(qpair->ctrlr));
return ret; return ret;
} }
qpair->state = VFIO_USER_QPAIR_ACTIVE;
} else if ((cc->bits.en == 0 && cc->bits.shn == 0) || } else if ((cc->bits.en == 0 && cc->bits.shn == 0) ||
(cc->bits.en == 1 && cc->bits.shn != 0)) { (cc->bits.en == 1 && cc->bits.shn != 0)) {
SPDK_DEBUGLOG(nvmf_vfio, SPDK_DEBUGLOG(nvmf_vfio,
"%s: UNMAP Admin queue\n", "%s: UNMAP Admin queue\n",
ctrlr_id(qpair->ctrlr)); ctrlr_id(qpair->ctrlr));
unmap_admin_queue(qpair->ctrlr); unmap_admin_queue(qpair->ctrlr);
qpair->state = VFIO_USER_QPAIR_INACTIVE;
} }
} }
} }