From 6b504fda5df6bd360a67940e3a57718e3ef0d0a5 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Tue, 12 Jun 2018 13:03:49 -0700 Subject: [PATCH] nvme/rdma: add timeout support to RDMA transport Change-Id: I3e53773570e66c1f52a6c29c6709684fc393717e Signed-off-by: Daniel Verkamp Reviewed-on: https://review.gerrithub.io/414883 Tested-by: SPDK Automated Test System Reviewed-by: Ben Walker Reviewed-by: Jim Harris --- lib/nvme/nvme_rdma.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/lib/nvme/nvme_rdma.c b/lib/nvme/nvme_rdma.c index e6e2f210d..c2f27ae0d 100644 --- a/lib/nvme/nvme_rdma.c +++ b/lib/nvme/nvme_rdma.c @@ -50,6 +50,7 @@ #include "spdk/nvmf_spec.h" #include "spdk/string.h" #include "spdk/endian.h" +#include "spdk/likely.h" #include "nvme_internal.h" @@ -1531,6 +1532,45 @@ nvme_rdma_qpair_fail(struct spdk_nvme_qpair *qpair) return 0; } +static void +nvme_rdma_qpair_check_timeout(struct spdk_nvme_qpair *qpair) +{ + uint64_t t02; + struct spdk_nvme_rdma_req *rdma_req, *tmp; + struct nvme_rdma_qpair *rqpair = nvme_rdma_qpair(qpair); + struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr; + struct spdk_nvme_ctrlr_process *active_proc; + + /* Don't check timeouts during controller initialization. */ + if (ctrlr->state != NVME_CTRLR_STATE_READY) { + return; + } + + if (nvme_qpair_is_admin_queue(qpair)) { + active_proc = spdk_nvme_ctrlr_get_current_process(ctrlr); + } else { + active_proc = qpair->active_proc; + } + + /* Only check timeouts if the current process has a timeout callback. */ + if (active_proc == NULL || active_proc->timeout_cb_fn == NULL) { + return; + } + + t02 = spdk_get_ticks(); + TAILQ_FOREACH_SAFE(rdma_req, &rqpair->outstanding_reqs, link, tmp) { + assert(rdma_req->req != NULL); + + if (nvme_request_check_timeout(rdma_req->req, rdma_req->id, active_proc, t02)) { + /* + * The requests are in order, so as soon as one has not timed out, + * stop iterating. + */ + break; + } + } +} + #define MAX_COMPLETIONS_PER_POLL 128 int @@ -1599,6 +1639,10 @@ nvme_rdma_qpair_process_completions(struct spdk_nvme_qpair *qpair, } } while (reaped < max_completions); + if (spdk_unlikely(rqpair->qpair.ctrlr->timeout_enabled)) { + nvme_rdma_qpair_check_timeout(qpair); + } + return reaped; }