All of lore.kernel.org
 help / color / mirror / Atom feed
From: Liu Song <liusong@linux.alibaba.com>
To: axboe@kernel.dk
Cc: linux-kernel@vger.kernel.org, linux-block@vger.kernel.org
Subject: [PATCH] sbitmap: fix permanent io blocking caused by insufficient wakeup times
Date: Sat, 17 Sep 2022 10:33:01 +0800	[thread overview]
Message-ID: <1663381981-6413-1-git-send-email-liusong@linux.alibaba.com> (raw)

From: Liu Song <liusong@linux.alibaba.com>

In "sbitmap_queue_clear_batch", a batch of completed requests may be
processed at once, but "wait_cnt" is only reduced once by
"sbitmap_queue_wake_up".
In our environment, if "/sys/block/nvme0n1/nr_requests" is adjusted to
32, it is easily because no tag and then enter the waiting situation,
if continue change "nr_requests" to 1023 at this time, it will basically
fall into the situation of permanent blocking. Because there will be
"blk_freeze_queue" in "blk_mq_update_nr_requests", which will prevent
any new requests, but due to insufficient wake-up, there are tasks
waiting for wake-up, but no new wake-up opportunities will be generated
at this time, so this situation needs to be repaired.

Signed-off-by: Liu Song <liusong@linux.alibaba.com>
---
 include/linux/sbitmap.h |  8 ++++++++
 lib/sbitmap.c           | 22 ++++++++++++++++++----
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h
index 8f5a86e..153382e 100644
--- a/include/linux/sbitmap.h
+++ b/include/linux/sbitmap.h
@@ -579,6 +579,14 @@ static inline struct sbq_wait_state *sbq_wait_ptr(struct sbitmap_queue *sbq,
 void sbitmap_queue_wake_up(struct sbitmap_queue *sbq);
 
 /**
+ * sbitmap_queue_wake_up_batch() - Attempt to wake up waiters in batches
+ * on a &struct sbitmap_queue.
+ * @sbq: Bitmap queue to wake up.
+ * @nr: The number of attempts to wake the waiter.
+ */
+void sbitmap_queue_wake_up_batch(struct sbitmap_queue *sbq, int nr);
+
+/**
  * sbitmap_queue_show() - Dump &struct sbitmap_queue information to a &struct
  * seq_file.
  * @sbq: Bitmap queue to show.
diff --git a/lib/sbitmap.c b/lib/sbitmap.c
index 29eb048..f2aa1da 100644
--- a/lib/sbitmap.c
+++ b/lib/sbitmap.c
@@ -600,7 +600,7 @@ static struct sbq_wait_state *sbq_wake_ptr(struct sbitmap_queue *sbq)
 	return NULL;
 }
 
-static bool __sbq_wake_up(struct sbitmap_queue *sbq)
+static bool __sbq_wake_up(struct sbitmap_queue *sbq, int *nr)
 {
 	struct sbq_wait_state *ws;
 	unsigned int wake_batch;
@@ -610,6 +610,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
 	if (!ws)
 		return false;
 
+again:
 	wait_cnt = atomic_dec_return(&ws->wait_cnt);
 	if (wait_cnt <= 0) {
 		int ret;
@@ -632,10 +633,14 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
 		if (ret == wait_cnt) {
 			sbq_index_atomic_inc(&sbq->wake_index);
 			wake_up_nr(&ws->wait, wake_batch);
-			return false;
+			if (!nr || *nr <= 0)
+				return false;
 		}
 
 		return true;
+	} else if (nr && *nr) {
+		(*nr)--;
+		goto again;
 	}
 
 	return false;
@@ -643,11 +648,20 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
 
 void sbitmap_queue_wake_up(struct sbitmap_queue *sbq)
 {
-	while (__sbq_wake_up(sbq))
+	while (__sbq_wake_up(sbq, NULL))
 		;
 }
 EXPORT_SYMBOL_GPL(sbitmap_queue_wake_up);
 
+void sbitmap_queue_wake_up_batch(struct sbitmap_queue *sbq, int nr)
+{
+	int i = SBQ_WAIT_QUEUES;
+
+	while (__sbq_wake_up(sbq, &nr) && --i)
+		;
+}
+EXPORT_SYMBOL_GPL(sbitmap_queue_wake_up_batch);
+
 static inline void sbitmap_update_cpu_hint(struct sbitmap *sb, int cpu, int tag)
 {
 	if (likely(!sb->round_robin && tag < sb->depth))
@@ -683,7 +697,7 @@ void sbitmap_queue_clear_batch(struct sbitmap_queue *sbq, int offset,
 		atomic_long_andnot(mask, (atomic_long_t *) addr);
 
 	smp_mb__after_atomic();
-	sbitmap_queue_wake_up(sbq);
+	sbitmap_queue_wake_up_batch(sbq, nr_tags);
 	sbitmap_update_cpu_hint(&sbq->sb, raw_smp_processor_id(),
 					tags[nr_tags - 1] - offset);
 }
-- 
1.8.3.1


             reply	other threads:[~2022-09-17  2:33 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-17  2:33 Liu Song [this message]
2022-09-17 10:20 ` [PATCH] sbitmap: fix permanent io blocking caused by insufficient wakeup times Yu Kuai
2022-09-17 15:06   ` Liu Song
     [not found] <20220917035831.735-1-hdanton@sina.com>
2022-09-17  9:10 ` Liu Song

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1663381981-6413-1-git-send-email-liusong@linux.alibaba.com \
    --to=liusong@linux.alibaba.com \
    --cc=axboe@kernel.dk \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.