[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241209115522.3741093-4-yukuai1@huaweicloud.com>
Date: Mon, 9 Dec 2024 19:55:22 +0800
From: Yu Kuai <yukuai1@...weicloud.com>
To: axboe@...nel.dk,
akpm@...ux-foundation.org,
yang.yang@...o.com,
ming.lei@...hat.com,
yukuai3@...wei.com,
bvanassche@....org,
osandov@...com,
paolo.valente@...aro.org
Cc: linux-block@...r.kernel.org,
linux-kernel@...r.kernel.org,
yukuai1@...weicloud.com,
yi.zhang@...wei.com,
yangerkun@...wei.com
Subject: [PATCH RFC 3/3] lib/sbitmap: fix shallow_depth tag allocation
From: Yu Kuai <yukuai3@...wei.com>
Currently, shallow_depth is used by bfq, kyber and mq-deadline, they both
pass in the value for the whole sbitmap, while sbitmap treate the value
for just one word. Which means, shallow_depth never work as expected,
and there really is no such functional tests to covert it.
Consider that callers doesn't know which word will be used, and how many
bits are available in the last word, fix this problem by treating
shallow_depth for the whole sbitmap in sbitmap_find_bit().
Fixes: 00e043936e9a ("blk-mq: introduce Kyber multiqueue I/O scheduler")
Fixes: a52a69ea89dc ("block, bfq: limit tags for writes and async I/O")
Fixes: 07757588e507 ("block/mq-deadline: Reserve 25% of scheduler tags for synchronous requests")
Signed-off-by: Yu Kuai <yukuai3@...wei.com>
---
include/linux/sbitmap.h | 2 +-
lib/sbitmap.c | 31 +++++++++++++++++++++++++------
2 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h
index e1730f5fdf9c..ffb9907c7070 100644
--- a/include/linux/sbitmap.h
+++ b/include/linux/sbitmap.h
@@ -461,7 +461,7 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags,
* sbitmap_queue, limiting the depth used from each word, with preemption
* already disabled.
* @sbq: Bitmap queue to allocate from.
- * @shallow_depth: The maximum number of bits to allocate from a single word.
+ * @shallow_depth: The maximum number of bits to allocate from the queue.
* See sbitmap_get_shallow().
*
* If you call this, make sure to call sbitmap_queue_min_shallow_depth() after
diff --git a/lib/sbitmap.c b/lib/sbitmap.c
index 9d4213ce7916..13831c7536a3 100644
--- a/lib/sbitmap.c
+++ b/lib/sbitmap.c
@@ -208,8 +208,27 @@ static int sbitmap_find_bit_in_word(struct sbitmap_word *map,
return nr;
}
+static unsigned int __map_depth_with_shallow(const struct sbitmap *sb,
+ int index,
+ unsigned int shallow_depth)
+{
+ unsigned int pre_word_bits = 0;
+
+ if (shallow_depth >= sb->depth)
+ return __map_depth(sb, index);
+
+ if (index > 0)
+ pre_word_bits += (index - 1) << sb->shift;
+
+ if (shallow_depth <= pre_word_bits)
+ return 0;
+
+ return min_t(unsigned int, __map_depth(sb, index),
+ shallow_depth - pre_word_bits);
+}
+
static int sbitmap_find_bit(struct sbitmap *sb,
- unsigned int depth,
+ unsigned int shallow_depth,
unsigned int index,
unsigned int alloc_hint,
bool wrap)
@@ -218,12 +237,12 @@ static int sbitmap_find_bit(struct sbitmap *sb,
int nr = -1;
for (i = 0; i < sb->map_nr; i++) {
- nr = sbitmap_find_bit_in_word(&sb->map[index],
- min_t(unsigned int,
- __map_depth(sb, index),
- depth),
- alloc_hint, wrap);
+ unsigned int depth = __map_depth_with_shallow(sb, index,
+ shallow_depth);
+ if (depth)
+ nr = sbitmap_find_bit_in_word(&sb->map[index], depth,
+ alloc_hint, wrap);
if (nr != -1) {
nr += index << sb->shift;
break;
--
2.39.2
Powered by blists - more mailing lists