From c65e726acdeca9ec1d1634f25300808c1a63500e Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Thu, 7 Jul 2016 08:51:16 -0700 Subject: [PATCH] nvme: Limit max completions in a single poll For a single poll of the completion queue, if the user submits I/O from within their completion callback and their completion callback is particularly slow to execute, the loop could potentially continue forever. To support this, we need to limit the number of completions we'll process in one batch. Change-Id: If6bae47e52b36347dbe5622ace68c866ee88a0b2 Signed-off-by: Ben Walker --- lib/nvme/nvme_qpair.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/nvme/nvme_qpair.c b/lib/nvme/nvme_qpair.c index 6bd8bf80a..b832e2c77 100644 --- a/lib/nvme/nvme_qpair.c +++ b/lib/nvme/nvme_qpair.c @@ -454,13 +454,14 @@ spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_ return 0; } - if (max_completions == 0) { + if (max_completions == 0 || (max_completions > (qpair->num_entries - 1U))) { + /* - * max_completions == 0 means unlimited; set it to the max uint32_t value - * to avoid a special case in the loop. The maximum possible queue size is - * only 64K, so num_completions will never reach this value. + * max_completions == 0 means unlimited, but complete at most one + * queue depth batch of I/O at a time so that the completion + * queue doorbells don't wrap around. */ - max_completions = UINT32_MAX; + max_completions = qpair->num_entries - 1; } while (1) {