nvme: make timeout function per process

Change-Id: I6e58baaeb09580b5f70e1acf5323376ca0b26bbf
Signed-off-by: Ziye Yang <optimistyzy@gmail.com>
Reviewed-on: https://review.gerrithub.io/407382
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Ziye Yang 2018-04-12 12:20:38 +08:00 committed by Daniel Verkamp
parent ebf079362b
commit 31bf5d795e
3 changed files with 32 additions and 24 deletions

View File

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

View File

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

View File

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