nvme: allow for deletion of I/O qpairs during their completion context

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: Ibc6566e9248cd7004aa5d4374f32b519062ed6d9
This commit is contained in:
Jim Harris 2017-03-01 22:35:04 -07:00
parent 1dbf53eebf
commit 37ccb50c50
4 changed files with 47 additions and 1 deletions

View File

@ -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);
@ -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);
}

View File

@ -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 */

View File

@ -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
@ -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;

View File

@ -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)