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:
parent
1dbf53eebf
commit
37ccb50c50
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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…
Reference in New Issue
Block a user