Commit 8b158aaa authored by Daniel Verkamp's avatar Daniel Verkamp Committed by Jim Harris
Browse files

nvme: factor out request timeout checking



This will be used in other transports as well.

Change-Id: I05026b0dfea2647d61a173379aca368ca48a2f52
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/413864


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent cdb3a594
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -206,6 +206,59 @@ nvme_allocate_request_user_copy(struct spdk_nvme_qpair *qpair,
	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
nvme_robust_mutex_init_shared(pthread_mutex_t *mtx)
{
+2 −0
Original line number Diff line number Diff line
@@ -735,6 +735,8 @@ nvme_free_request(struct nvme_request *req)
}

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

int	nvme_robust_mutex_init_shared(pthread_mutex_t *mtx);
+3 −26
Original line number Diff line number Diff line
@@ -2003,36 +2003,13 @@ nvme_pcie_qpair_check_timeout(struct spdk_nvme_qpair *qpair)
	TAILQ_FOREACH_SAFE(tr, &pqpair->outstanding_tr, tq_list, tmp) {
		assert(tr->req != NULL);

		if (tr->req->timed_out || tr->req->submit_tick == 0) {
			continue;
		}

		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,
		if (nvme_request_check_timeout(tr->req, tr->cid, active_proc, t02)) {
			/*
			 * The requests are in order, so as soon as one has not timed out,
			 * stop iterating.
			 */
			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);
	}
}

+8 −0
Original line number Diff line number Diff line
@@ -288,6 +288,14 @@ nvme_qpair_enable(struct spdk_nvme_qpair *qpair)
	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 *
spdk_nvme_get_ctrlr_by_trid_unsafe(const struct spdk_nvme_transport_id *trid)
{