nvme: factor out request timeout checking
This will be used in other transports as well. Change-Id: I05026b0dfea2647d61a173379aca368ca48a2f52 Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-on: https://review.gerrithub.io/413864 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
cdb3a594a8
commit
8b158aaacd
@ -206,6 +206,59 @@ nvme_allocate_request_user_copy(struct spdk_nvme_qpair *qpair,
|
|||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a request has exceeded the controller timeout.
|
||||||
|
*
|
||||||
|
* \param req request to check for timeout.
|
||||||
|
* \param cid command ID for command submitted by req (will be passed to timeout_cb_fn)
|
||||||
|
* \param active_proc per-process data for the controller associated with req
|
||||||
|
* \param now_tick current time from spdk_get_ticks()
|
||||||
|
* \return 0 if requests submitted more recently than req should still be checked for timeouts, or
|
||||||
|
* 1 if requests newer than req need not be checked.
|
||||||
|
*
|
||||||
|
* The request's timeout callback will be called if needed; the caller is only responsible for
|
||||||
|
* calling this function on each outstanding request.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
nvme_request_check_timeout(struct nvme_request *req, uint16_t cid,
|
||||||
|
struct spdk_nvme_ctrlr_process *active_proc,
|
||||||
|
uint64_t now_tick)
|
||||||
|
{
|
||||||
|
struct spdk_nvme_qpair *qpair = req->qpair;
|
||||||
|
struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr;
|
||||||
|
|
||||||
|
assert(active_proc->timeout_cb_fn != NULL);
|
||||||
|
|
||||||
|
if (req->timed_out || req->submit_tick == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->pid != g_spdk_nvme_pid) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nvme_qpair_is_admin_queue(qpair) &&
|
||||||
|
req->cmd.opc == SPDK_NVME_OPC_ASYNC_EVENT_REQUEST) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->submit_tick + active_proc->timeout_ticks > now_tick) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
req->timed_out = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
active_proc->timeout_cb_fn(active_proc->timeout_cb_arg, ctrlr,
|
||||||
|
nvme_qpair_is_admin_queue(qpair) ? NULL : qpair,
|
||||||
|
cid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nvme_robust_mutex_init_shared(pthread_mutex_t *mtx)
|
nvme_robust_mutex_init_shared(pthread_mutex_t *mtx)
|
||||||
{
|
{
|
||||||
|
@ -735,6 +735,8 @@ nvme_free_request(struct nvme_request *req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void nvme_request_remove_child(struct nvme_request *parent, struct nvme_request *child);
|
void nvme_request_remove_child(struct nvme_request *parent, struct nvme_request *child);
|
||||||
|
int nvme_request_check_timeout(struct nvme_request *req, uint16_t cid,
|
||||||
|
struct spdk_nvme_ctrlr_process *active_proc, uint64_t now_tick);
|
||||||
uint64_t nvme_get_quirks(const struct spdk_pci_id *id);
|
uint64_t nvme_get_quirks(const struct spdk_pci_id *id);
|
||||||
|
|
||||||
int nvme_robust_mutex_init_shared(pthread_mutex_t *mtx);
|
int nvme_robust_mutex_init_shared(pthread_mutex_t *mtx);
|
||||||
|
@ -2003,36 +2003,13 @@ nvme_pcie_qpair_check_timeout(struct spdk_nvme_qpair *qpair)
|
|||||||
TAILQ_FOREACH_SAFE(tr, &pqpair->outstanding_tr, tq_list, tmp) {
|
TAILQ_FOREACH_SAFE(tr, &pqpair->outstanding_tr, tq_list, tmp) {
|
||||||
assert(tr->req != NULL);
|
assert(tr->req != NULL);
|
||||||
|
|
||||||
if (tr->req->timed_out || tr->req->submit_tick == 0) {
|
if (nvme_request_check_timeout(tr->req, tr->cid, active_proc, t02)) {
|
||||||
continue;
|
/*
|
||||||
}
|
* The requests are in order, so as soon as one has not timed out,
|
||||||
|
|
||||||
if (nvme_qpair_is_admin_queue(qpair)) {
|
|
||||||
if (tr->req->pid != getpid()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tr->req->cmd.opc == SPDK_NVME_OPC_ASYNC_EVENT_REQUEST) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tr->req->submit_tick + active_proc->timeout_ticks > t02) {
|
|
||||||
/* The trackers are in order, so as soon as one has not timed out,
|
|
||||||
* stop iterating.
|
* stop iterating.
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr->req->timed_out = true;
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
*/
|
|
||||||
active_proc->timeout_cb_fn(active_proc->timeout_cb_arg, ctrlr,
|
|
||||||
nvme_qpair_is_admin_queue(qpair) ? NULL : qpair,
|
|
||||||
tr->cid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +288,14 @@ nvme_qpair_enable(struct spdk_nvme_qpair *qpair)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nvme_request_check_timeout(struct nvme_request *req, uint16_t cid,
|
||||||
|
struct spdk_nvme_ctrlr_process *active_proc,
|
||||||
|
uint64_t now_tick)
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
struct spdk_nvme_ctrlr *
|
struct spdk_nvme_ctrlr *
|
||||||
spdk_nvme_get_ctrlr_by_trid_unsafe(const struct spdk_nvme_transport_id *trid)
|
spdk_nvme_get_ctrlr_by_trid_unsafe(const struct spdk_nvme_transport_id *trid)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user