Loading lib/nvme/nvme_ctrlr.c +17 −0 Original line number Diff line number Diff line Loading @@ -205,6 +205,17 @@ spdk_nvme_ctrlr_free_io_qpair(struct spdk_nvme_qpair *qpair) ctrlr = qpair->ctrlr; if (qpair->in_completion_context) { /* * There are many cases where it is convenient to delete an io qpair in the context * of that qpair's completion routine. To handle this properly, set a flag here * so that the completion routine will perform an actual delete after the context * unwinds. */ qpair->delete_after_completion_context = 1; return 0; } nvme_robust_mutex_lock(&ctrlr->ctrlr_lock); nvme_ctrlr_proc_remove_io_qpair(qpair); Loading Loading @@ -947,6 +958,12 @@ nvme_ctrlr_cleanup_process(struct spdk_nvme_ctrlr_process *proc) TAILQ_FOREACH_SAFE(qpair, &proc->allocated_io_qpairs, per_process_tailq, tmp_qpair) { TAILQ_REMOVE(&proc->allocated_io_qpairs, qpair, per_process_tailq); /* * The process may have been killed while some qpairs were in their * completion context. Clear that flag here to allow these IO * qpairs to be deleted. */ qpair->in_completion_context = 0; spdk_nvme_ctrlr_free_io_qpair(qpair); } Loading lib/nvme/nvme_internal.h +8 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,14 @@ struct spdk_nvme_qpair { uint8_t qprio; /* * Members for handling IO qpair deletion inside of a completion context. * These are specifically defined as single bits, so that they do not * push this data structure out to another cacheline. */ uint8_t in_completion_context : 1; uint8_t delete_after_completion_context: 1; struct spdk_nvme_ctrlr *ctrlr; /* List entry for spdk_nvme_ctrlr::active_io_qpairs */ Loading lib/nvme/nvme_qpair.c +16 −1 Original line number Diff line number Diff line Loading @@ -338,12 +338,24 @@ nvme_qpair_manual_complete_request(struct spdk_nvme_qpair *qpair, int32_t spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions) { int32_t ret; if (qpair->ctrlr->is_failed) { nvme_qpair_fail(qpair); return 0; } return nvme_transport_qpair_process_completions(qpair, max_completions); qpair->in_completion_context = 1; ret = nvme_transport_qpair_process_completions(qpair, max_completions); qpair->in_completion_context = 0; if (qpair->delete_after_completion_context) { /* * A request to delete this qpair was made in the context of this completion * routine - so it is safe to delete it now. */ spdk_nvme_ctrlr_free_io_qpair(qpair); } return ret; } int Loading @@ -354,6 +366,9 @@ nvme_qpair_init(struct spdk_nvme_qpair *qpair, uint16_t id, qpair->id = id; qpair->qprio = qprio; qpair->in_completion_context = 0; qpair->delete_after_completion_context = 0; qpair->ctrlr = ctrlr; qpair->trtype = ctrlr->trid.trtype; Loading test/lib/nvme/unit/nvme_qpair_c/nvme_qpair_ut.c +6 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,12 @@ nvme_transport_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t return 0; } int spdk_nvme_ctrlr_free_io_qpair(struct spdk_nvme_qpair *qpair) { return 0; } static void prepare_submit_request_test(struct spdk_nvme_qpair *qpair, struct spdk_nvme_ctrlr *ctrlr) Loading Loading
lib/nvme/nvme_ctrlr.c +17 −0 Original line number Diff line number Diff line Loading @@ -205,6 +205,17 @@ spdk_nvme_ctrlr_free_io_qpair(struct spdk_nvme_qpair *qpair) ctrlr = qpair->ctrlr; if (qpair->in_completion_context) { /* * There are many cases where it is convenient to delete an io qpair in the context * of that qpair's completion routine. To handle this properly, set a flag here * so that the completion routine will perform an actual delete after the context * unwinds. */ qpair->delete_after_completion_context = 1; return 0; } nvme_robust_mutex_lock(&ctrlr->ctrlr_lock); nvme_ctrlr_proc_remove_io_qpair(qpair); Loading Loading @@ -947,6 +958,12 @@ nvme_ctrlr_cleanup_process(struct spdk_nvme_ctrlr_process *proc) TAILQ_FOREACH_SAFE(qpair, &proc->allocated_io_qpairs, per_process_tailq, tmp_qpair) { TAILQ_REMOVE(&proc->allocated_io_qpairs, qpair, per_process_tailq); /* * The process may have been killed while some qpairs were in their * completion context. Clear that flag here to allow these IO * qpairs to be deleted. */ qpair->in_completion_context = 0; spdk_nvme_ctrlr_free_io_qpair(qpair); } Loading
lib/nvme/nvme_internal.h +8 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,14 @@ struct spdk_nvme_qpair { uint8_t qprio; /* * Members for handling IO qpair deletion inside of a completion context. * These are specifically defined as single bits, so that they do not * push this data structure out to another cacheline. */ uint8_t in_completion_context : 1; uint8_t delete_after_completion_context: 1; struct spdk_nvme_ctrlr *ctrlr; /* List entry for spdk_nvme_ctrlr::active_io_qpairs */ Loading
lib/nvme/nvme_qpair.c +16 −1 Original line number Diff line number Diff line Loading @@ -338,12 +338,24 @@ nvme_qpair_manual_complete_request(struct spdk_nvme_qpair *qpair, int32_t spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions) { int32_t ret; if (qpair->ctrlr->is_failed) { nvme_qpair_fail(qpair); return 0; } return nvme_transport_qpair_process_completions(qpair, max_completions); qpair->in_completion_context = 1; ret = nvme_transport_qpair_process_completions(qpair, max_completions); qpair->in_completion_context = 0; if (qpair->delete_after_completion_context) { /* * A request to delete this qpair was made in the context of this completion * routine - so it is safe to delete it now. */ spdk_nvme_ctrlr_free_io_qpair(qpair); } return ret; } int Loading @@ -354,6 +366,9 @@ nvme_qpair_init(struct spdk_nvme_qpair *qpair, uint16_t id, qpair->id = id; qpair->qprio = qprio; qpair->in_completion_context = 0; qpair->delete_after_completion_context = 0; qpair->ctrlr = ctrlr; qpair->trtype = ctrlr->trid.trtype; Loading
test/lib/nvme/unit/nvme_qpair_c/nvme_qpair_ut.c +6 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,12 @@ nvme_transport_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t return 0; } int spdk_nvme_ctrlr_free_io_qpair(struct spdk_nvme_qpair *qpair) { return 0; } static void prepare_submit_request_test(struct spdk_nvme_qpair *qpair, struct spdk_nvme_ctrlr *ctrlr) Loading