From 31bf5d795e5464ba7d152d6705293221c6efa2ec Mon Sep 17 00:00:00 2001 From: Ziye Yang Date: Thu, 12 Apr 2018 12:20:38 +0800 Subject: [PATCH] nvme: make timeout function per process Change-Id: I6e58baaeb09580b5f70e1acf5323376ca0b26bbf Signed-off-by: Ziye Yang Reviewed-on: https://review.gerrithub.io/407382 Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp Reviewed-by: Ben Walker --- lib/nvme/nvme_ctrlr.c | 21 +++++++++++++++------ lib/nvme/nvme_internal.h | 15 +++++++++------ lib/nvme/nvme_pcie.c | 20 ++++++++------------ 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 28bf04c2d..24c3e1d36 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -152,6 +152,7 @@ nvme_ctrlr_proc_add_io_qpair(struct spdk_nvme_qpair *qpair) if (active_proc->pid == pid) { TAILQ_INSERT_TAIL(&active_proc->allocated_io_qpairs, qpair, per_process_tailq); + qpair->active_proc = active_proc; break; } } @@ -1728,9 +1729,6 @@ nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr) } TAILQ_INIT(&ctrlr->active_procs); - ctrlr->timeout_cb_fn = NULL; - ctrlr->timeout_cb_arg = NULL; - ctrlr->timeout_ticks = 0; return rc; } @@ -1967,9 +1965,20 @@ void spdk_nvme_ctrlr_register_timeout_callback(struct spdk_nvme_ctrlr *ctrlr, uint32_t nvme_timeout, spdk_nvme_timeout_cb cb_fn, void *cb_arg) { - ctrlr->timeout_ticks = nvme_timeout * spdk_get_ticks_hz(); - ctrlr->timeout_cb_fn = cb_fn; - ctrlr->timeout_cb_arg = cb_arg; + struct spdk_nvme_ctrlr_process *active_proc = NULL; + pid_t pid = getpid(); + + TAILQ_FOREACH(active_proc, &ctrlr->active_procs, tailq) { + if (active_proc->pid == pid) { + break; + } + } + + assert(active_proc != NULL); + + active_proc->timeout_ticks = nvme_timeout * spdk_get_ticks_hz(); + active_proc->timeout_cb_fn = cb_fn; + active_proc->timeout_cb_arg = cb_arg; } bool diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index 2548349c9..ccbc11bc4 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -282,6 +282,8 @@ struct spdk_nvme_qpair { /* List entry for spdk_nvme_ctrlr_process::allocated_io_qpairs */ TAILQ_ENTRY(spdk_nvme_qpair) per_process_tailq; + struct spdk_nvme_ctrlr_process *active_proc; + void *req_buf; }; @@ -367,6 +369,13 @@ struct spdk_nvme_ctrlr_process { /** Allocated IO qpairs */ TAILQ_HEAD(, spdk_nvme_qpair) allocated_io_qpairs; + + /** + * A function pointer to timeout callback function + */ + spdk_nvme_timeout_cb timeout_cb_fn; + void *timeout_cb_arg; + uint64_t timeout_ticks; }; /* @@ -466,12 +475,6 @@ struct spdk_nvme_ctrlr { /** Track all the processes manage this controller */ TAILQ_HEAD(, spdk_nvme_ctrlr_process) active_procs; - /** - * A function pointer to timeout callback function - */ - spdk_nvme_timeout_cb timeout_cb_fn; - void *timeout_cb_arg; - uint64_t timeout_ticks; STAILQ_HEAD(, nvme_request) queued_aborts; uint32_t outstanding_aborts; diff --git a/lib/nvme/nvme_pcie.c b/lib/nvme/nvme_pcie.c index 6b45be17c..cefe4c2a1 100644 --- a/lib/nvme/nvme_pcie.c +++ b/lib/nvme/nvme_pcie.c @@ -1173,7 +1173,7 @@ nvme_pcie_qpair_submit_tracker(struct spdk_nvme_qpair *qpair, struct nvme_tracke struct nvme_pcie_ctrlr *pctrlr = nvme_pcie_ctrlr(qpair->ctrlr); tr->timed_out = 0; - if (spdk_unlikely(qpair->ctrlr->timeout_cb_fn != NULL)) { + if (spdk_unlikely(qpair->active_proc && qpair->active_proc->timeout_cb_fn != NULL)) { tr->submit_tick = spdk_get_ticks(); } @@ -2006,14 +2006,6 @@ nvme_pcie_qpair_check_timeout(struct spdk_nvme_qpair *qpair) struct nvme_pcie_qpair *pqpair = nvme_pcie_qpair(qpair); struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr; - /* We don't want to expose the admin queue to the user, - * so when we're timing out admin commands set the - * qpair to NULL. - */ - if (qpair == ctrlr->adminq) { - qpair = NULL; - } - t02 = spdk_get_ticks(); TAILQ_FOREACH_SAFE(tr, &pqpair->outstanding_tr, tq_list, tmp) { if (tr->timed_out) { @@ -2025,7 +2017,7 @@ nvme_pcie_qpair_check_timeout(struct spdk_nvme_qpair *qpair) continue; } - if (tr->submit_tick + ctrlr->timeout_ticks > t02) { + if (tr->submit_tick + qpair->active_proc->timeout_ticks > t02) { /* The trackers are in order, so as soon as one has not timed out, * stop iterating. */ @@ -2033,7 +2025,7 @@ nvme_pcie_qpair_check_timeout(struct spdk_nvme_qpair *qpair) } tr->timed_out = 1; - ctrlr->timeout_cb_fn(ctrlr->timeout_cb_arg, ctrlr, qpair, tr->cid); + qpair->active_proc->timeout_cb_fn(qpair->active_proc->timeout_cb_arg, ctrlr, qpair, tr->cid); } } @@ -2116,7 +2108,11 @@ nvme_pcie_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_ g_thread_mmio_ctrlr = NULL; } - if (spdk_unlikely(qpair->ctrlr->timeout_cb_fn != NULL) && + /* We don't want to expose the admin queue to the user, + * so when we're timing out admin commands set the + * qpair to NULL. + */ + if (!nvme_qpair_is_admin_queue(qpair) && spdk_unlikely(qpair->active_proc->timeout_cb_fn != NULL) && qpair->ctrlr->state == NVME_CTRLR_STATE_READY) { /* * User registered for timeout callback