linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] lib/sbitmap: convert shallow_depth from one word to the whole sbitmap
@ 2025-08-05  7:37 Yu Kuai
  2025-08-05  7:37 ` [PATCH v3 1/2] " Yu Kuai
  2025-08-05  7:37 ` [PATCH v3 2/2] lib/sbitmap: make sbitmap_get_shallow() internal Yu Kuai
  0 siblings, 2 replies; 8+ messages in thread
From: Yu Kuai @ 2025-08-05  7:37 UTC (permalink / raw)
  To: yukuai3, axboe, akpm, ming.lei, dlemoal, jack
  Cc: linux-block, linux-kernel, yukuai1, yi.zhang, yangerkun,
	johnny.chenyi

From: Yu Kuai <yukuai3@huawei.com>

Changes from v2:
 - split shallow_depth to each word in patch 1, suggested by Jan;
 - add review tag by Jan in patch 2
Changes from v1:
 - fix some wording in patch 2
 - add review tag by Damien in patch 2

Currently elevators will record internal 'async_depth' to throttle
asynchronous requests, and they both calculate shallow_dpeth based on
sb->shift, with the respect that sb->shift is the available tags in one
word.

However, sb->shift is not the availbale tags in the last word, see
__map_depth:

if (index == sb->map_nr - 1)
  return sb->depth - (index << sb->shift);

For consequence, if the last word is used, more tags can be get than
expected, for example, assume nr_requests=256 and there are four words,
in the worst case if user set nr_requests=32, then the first word is
the last word, and still use bits per word, which is 64, to calculate
async_depth is wrong.

One the ohter hand, due to cgroup qos, bfq can allow only one request
to be allocated, and set shallow_dpeth=1 will still allow the number
of words request to be allocated.

Fix those problems by using shallow_depth to the whole sbitmap instead
of per word, also change kyber, mq-deadline and bfq to follow this,
a new helper __map_depth_with_shallow() is introduced to calculate
available bits in each word.

An example how shallow_depth is splited to each word:

assume sb->depth is 32 + 32 + 32 + 16

shallow_depth word0 word1 word2 word3
1: 1 0 0 0
2: 1 1 0 0
3: 1 1 1 0
4: 1 1 1 1
5: 2 1 1 1
6: 2 2 1 1
7: 2 2 2 1
8: 3 2 2 1
9: 3 3 2 1
10: 3 3 3 1
11: 3 3 3 2
12: 4 3 3 2
13: 4 4 3 2
14: 4 4 4 2
15: 5 4 4 2
16: 5 5 4 2
17: 5 5 5 2
18: 5 5 5 3
19: 6 5 5 3
20: 6 6 5 3
21: 6 6 6 3
22: 7 6 6 3
23: 7 7 6 3
24: 7 7 7 3
25: 7 7 7 4
26: 8 7 7 4
27: 8 8 7 4
28: 8 8 8 4
29: 9 8 8 4
30: 9 9 8 4
31: 9 9 9 4
32: 9 9 9 5
33: 10 9 9 5
34: 10 10 9 5
35: 10 10 10 5
36: 11 10 10 5
37: 11 11 10 5
38: 11 11 11 5
39: 11 11 11 6
40: 12 11 11 6
41: 12 12 11 6
42: 12 12 12 6
43: 13 12 12 6
44: 13 13 12 6
45: 13 13 13 6
46: 13 13 13 7
47: 14 13 13 7
48: 14 14 13 7
49: 14 14 14 7
50: 15 14 14 7
51: 15 15 14 7
52: 15 15 15 7
53: 15 15 15 8
54: 16 15 15 8
55: 16 16 15 8
56: 16 16 16 8
57: 17 16 16 8
58: 17 17 16 8
59: 17 17 17 8
60: 17 17 17 9
61: 18 17 17 9
62: 18 18 17 9
63: 18 18 18 9
64: 19 18 18 9
65: 19 19 18 9
66: 19 19 19 9
67: 19 19 19 10
68: 20 19 19 10
69: 20 20 19 10
70: 20 20 20 10
71: 21 20 20 10
72: 21 21 20 10
73: 21 21 21 10
74: 21 21 21 11
75: 22 21 21 11
76: 22 22 21 11
77: 22 22 22 11
78: 23 22 22 11
79: 23 23 22 11
80: 23 23 23 11
81: 23 23 23 12
82: 24 23 23 12
83: 24 24 23 12
84: 24 24 24 12
85: 25 24 24 12
86: 25 25 24 12
87: 25 25 25 12
88: 25 25 25 13
89: 26 25 25 13
90: 26 26 25 13
91: 26 26 26 13
92: 27 26 26 13
93: 27 27 26 13
94: 27 27 27 13
95: 27 27 27 14
96: 28 27 27 14
97: 28 28 27 14
98: 28 28 28 14
99: 29 28 28 14
100: 29 29 28 14
101: 29 29 29 14
102: 29 29 29 15
103: 30 29 29 15
104: 30 30 29 15
105: 30 30 30 15
106: 31 30 30 15
107: 31 31 30 15
108: 31 31 31 15
109: 31 31 31 16
110: 32 31 31 16
111: 32 32 31 16

Yu Kuai (2):
  lib/sbitmap: convert shallow_depth from one word to the whole sbitmap
  lib/sbitmap: make sbitmap_get_shallow() internal

 block/bfq-iosched.c     | 35 +++++++++-----------
 block/bfq-iosched.h     |  3 +-
 block/kyber-iosched.c   |  9 ++---
 block/mq-deadline.c     | 16 +--------
 include/linux/sbitmap.h | 19 +----------
 lib/sbitmap.c           | 73 +++++++++++++++++++++++++----------------
 6 files changed, 65 insertions(+), 90 deletions(-)

-- 
2.39.2


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v3 1/2] lib/sbitmap: convert shallow_depth from one word to the whole sbitmap
  2025-08-05  7:37 [PATCH v3 0/2] lib/sbitmap: convert shallow_depth from one word to the whole sbitmap Yu Kuai
@ 2025-08-05  7:37 ` Yu Kuai
  2025-08-06  9:41   ` kernel test robot
  2025-08-05  7:37 ` [PATCH v3 2/2] lib/sbitmap: make sbitmap_get_shallow() internal Yu Kuai
  1 sibling, 1 reply; 8+ messages in thread
From: Yu Kuai @ 2025-08-05  7:37 UTC (permalink / raw)
  To: yukuai3, axboe, akpm, ming.lei, dlemoal, jack
  Cc: linux-block, linux-kernel, yukuai1, yi.zhang, yangerkun,
	johnny.chenyi

From: Yu Kuai <yukuai3@huawei.com>

Currently elevators will record internal 'async_depth' to throttle
asynchronous requests, and they both calculate shallow_dpeth based on
sb->shift, with the respect that sb->shift is the available tags in one
word.

However, sb->shift is not the availbale tags in the last word, see
__map_depth:

if (index == sb->map_nr - 1)
  return sb->depth - (index << sb->shift);

For consequence, if the last word is used, more tags can be get than
expected, for example, assume nr_requests=256 and there are four words,
in the worst case if user set nr_requests=32, then the first word is
the last word, and still use bits per word, which is 64, to calculate
async_depth is wrong.

One the ohter hand, due to cgroup qos, bfq can allow only one request
to be allocated, and set shallow_dpeth=1 will still allow the number
of words request to be allocated.

Fix those problems by using shallow_depth to the whole sbitmap instead
of per word, also change kyber, mq-deadline and bfq to follow this,
a new helper __map_depth_with_shallow() is introduced to calculate
available bits in each word.

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
 block/bfq-iosched.c     | 35 ++++++++++++--------------
 block/bfq-iosched.h     |  3 +--
 block/kyber-iosched.c   |  9 ++-----
 block/mq-deadline.c     | 16 +-----------
 include/linux/sbitmap.h |  6 ++---
 lib/sbitmap.c           | 55 +++++++++++++++++++++--------------------
 6 files changed, 51 insertions(+), 73 deletions(-)

diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 0cb1e9873aab..d68da9e92e1e 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -701,17 +701,13 @@ static void bfq_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data)
 {
 	struct bfq_data *bfqd = data->q->elevator->elevator_data;
 	struct bfq_io_cq *bic = bfq_bic_lookup(data->q);
-	int depth;
-	unsigned limit = data->q->nr_requests;
-	unsigned int act_idx;
+	unsigned int limit, act_idx;
 
 	/* Sync reads have full depth available */
-	if (op_is_sync(opf) && !op_is_write(opf)) {
-		depth = 0;
-	} else {
-		depth = bfqd->word_depths[!!bfqd->wr_busy_queues][op_is_sync(opf)];
-		limit = (limit * depth) >> bfqd->full_depth_shift;
-	}
+	if (op_is_sync(opf) && !op_is_write(opf))
+		limit = data->q->nr_requests;
+	else
+		limit = bfqd->async_depths[!!bfqd->wr_busy_queues][op_is_sync(opf)];
 
 	for (act_idx = 0; bic && act_idx < bfqd->num_actuators; act_idx++) {
 		/* Fast path to check if bfqq is already allocated. */
@@ -725,14 +721,16 @@ static void bfq_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data)
 		 * available requests and thus starve other entities.
 		 */
 		if (bfqq_request_over_limit(bfqd, bic, opf, act_idx, limit)) {
-			depth = 1;
+			limit = 1;
 			break;
 		}
 	}
+
 	bfq_log(bfqd, "[%s] wr_busy %d sync %d depth %u",
-		__func__, bfqd->wr_busy_queues, op_is_sync(opf), depth);
-	if (depth)
-		data->shallow_depth = depth;
+		__func__, bfqd->wr_busy_queues, op_is_sync(opf), limit);
+
+	if (limit < data->q->nr_requests)
+		data->shallow_depth = limit;
 }
 
 static struct bfq_queue *
@@ -7128,9 +7126,8 @@ void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg)
  */
 static void bfq_update_depths(struct bfq_data *bfqd, struct sbitmap_queue *bt)
 {
-	unsigned int depth = 1U << bt->sb.shift;
+	unsigned int nr_requests = bfqd->queue->nr_requests;
 
-	bfqd->full_depth_shift = bt->sb.shift;
 	/*
 	 * In-word depths if no bfq_queue is being weight-raised:
 	 * leaving 25% of tags only for sync reads.
@@ -7142,13 +7139,13 @@ static void bfq_update_depths(struct bfq_data *bfqd, struct sbitmap_queue *bt)
 	 * limit 'something'.
 	 */
 	/* no more than 50% of tags for async I/O */
-	bfqd->word_depths[0][0] = max(depth >> 1, 1U);
+	bfqd->async_depths[0][0] = max(nr_requests >> 1, 1U);
 	/*
 	 * no more than 75% of tags for sync writes (25% extra tags
 	 * w.r.t. async I/O, to prevent async I/O from starving sync
 	 * writes)
 	 */
-	bfqd->word_depths[0][1] = max((depth * 3) >> 2, 1U);
+	bfqd->async_depths[0][1] = max((nr_requests * 3) >> 2, 1U);
 
 	/*
 	 * In-word depths in case some bfq_queue is being weight-
@@ -7158,9 +7155,9 @@ static void bfq_update_depths(struct bfq_data *bfqd, struct sbitmap_queue *bt)
 	 * shortage.
 	 */
 	/* no more than ~18% of tags for async I/O */
-	bfqd->word_depths[1][0] = max((depth * 3) >> 4, 1U);
+	bfqd->async_depths[1][0] = max((nr_requests * 3) >> 4, 1U);
 	/* no more than ~37% of tags for sync writes (~20% extra tags) */
-	bfqd->word_depths[1][1] = max((depth * 6) >> 4, 1U);
+	bfqd->async_depths[1][1] = max((nr_requests * 6) >> 4, 1U);
 }
 
 static void bfq_depth_updated(struct blk_mq_hw_ctx *hctx)
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
index 687a3a7ba784..31217f196f4f 100644
--- a/block/bfq-iosched.h
+++ b/block/bfq-iosched.h
@@ -813,8 +813,7 @@ struct bfq_data {
 	 * Depth limits used in bfq_limit_depth (see comments on the
 	 * function)
 	 */
-	unsigned int word_depths[2][2];
-	unsigned int full_depth_shift;
+	unsigned int async_depths[2][2];
 
 	/*
 	 * Number of independent actuators. This is equal to 1 in
diff --git a/block/kyber-iosched.c b/block/kyber-iosched.c
index 4dba8405bd01..bfd9a40bb33d 100644
--- a/block/kyber-iosched.c
+++ b/block/kyber-iosched.c
@@ -157,10 +157,7 @@ struct kyber_queue_data {
 	 */
 	struct sbitmap_queue domain_tokens[KYBER_NUM_DOMAINS];
 
-	/*
-	 * Async request percentage, converted to per-word depth for
-	 * sbitmap_get_shallow().
-	 */
+	/* Number of allowed async requests. */
 	unsigned int async_depth;
 
 	struct kyber_cpu_latency __percpu *cpu_latency;
@@ -454,10 +451,8 @@ static void kyber_depth_updated(struct blk_mq_hw_ctx *hctx)
 {
 	struct kyber_queue_data *kqd = hctx->queue->elevator->elevator_data;
 	struct blk_mq_tags *tags = hctx->sched_tags;
-	unsigned int shift = tags->bitmap_tags.sb.shift;
-
-	kqd->async_depth = (1U << shift) * KYBER_ASYNC_PERCENT / 100U;
 
+	kqd->async_depth = hctx->queue->nr_requests * KYBER_ASYNC_PERCENT / 100U;
 	sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, kqd->async_depth);
 }
 
diff --git a/block/mq-deadline.c b/block/mq-deadline.c
index 2edf1cac06d5..9ab6c6256695 100644
--- a/block/mq-deadline.c
+++ b/block/mq-deadline.c
@@ -487,20 +487,6 @@ static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx)
 	return rq;
 }
 
-/*
- * 'depth' is a number in the range 1..INT_MAX representing a number of
- * requests. Scale it with a factor (1 << bt->sb.shift) / q->nr_requests since
- * 1..(1 << bt->sb.shift) is the range expected by sbitmap_get_shallow().
- * Values larger than q->nr_requests have the same effect as q->nr_requests.
- */
-static int dd_to_word_depth(struct blk_mq_hw_ctx *hctx, unsigned int qdepth)
-{
-	struct sbitmap_queue *bt = &hctx->sched_tags->bitmap_tags;
-	const unsigned int nrr = hctx->queue->nr_requests;
-
-	return ((qdepth << bt->sb.shift) + nrr - 1) / nrr;
-}
-
 /*
  * Called by __blk_mq_alloc_request(). The shallow_depth value set by this
  * function is used by __blk_mq_get_tag().
@@ -517,7 +503,7 @@ static void dd_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data)
 	 * Throttle asynchronous requests and writes such that these requests
 	 * do not block the allocation of synchronous requests.
 	 */
-	data->shallow_depth = dd_to_word_depth(data->hctx, dd->async_depth);
+	data->shallow_depth = dd->async_depth;
 }
 
 /* Called by blk_mq_update_nr_requests(). */
diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h
index 189140bf11fc..4adf4b364fcd 100644
--- a/include/linux/sbitmap.h
+++ b/include/linux/sbitmap.h
@@ -213,12 +213,12 @@ int sbitmap_get(struct sbitmap *sb);
  * sbitmap_get_shallow() - Try to allocate a free bit from a &struct sbitmap,
  * limiting the depth used from each word.
  * @sb: Bitmap 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 bitmap.
  *
  * This rather specific operation allows for having multiple users with
  * different allocation limits. E.g., there can be a high-priority class that
  * uses sbitmap_get() and a low-priority class that uses sbitmap_get_shallow()
- * with a @shallow_depth of (1 << (@sb->shift - 1)). Then, the low-priority
+ * with a @shallow_depth of (sb->depth >> 1). Then, the low-priority
  * class can only allocate half of the total bits in the bitmap, preventing it
  * from starving out the high-priority class.
  *
@@ -478,7 +478,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 d3412984170c..89be98859d5a 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 word_depth, shallow_word_depth, reminder;
+
+	word_depth = __map_depth(sb, index);
+	if (shallow_depth >= sb->depth)
+		return word_depth;
+
+	shallow_word_depth = word_depth * shallow_depth;
+	reminder = do_div(shallow_word_depth, sb->depth);
+
+	if (reminder >= (index + 1) * word_depth)
+		shallow_word_depth++;
+
+	return shallow_word_depth;
+}
+
 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;
@@ -406,27 +425,9 @@ EXPORT_SYMBOL_GPL(sbitmap_bitmap_show);
 static unsigned int sbq_calc_wake_batch(struct sbitmap_queue *sbq,
 					unsigned int depth)
 {
-	unsigned int wake_batch;
-	unsigned int shallow_depth;
-
-	/*
-	 * Each full word of the bitmap has bits_per_word bits, and there might
-	 * be a partial word. There are depth / bits_per_word full words and
-	 * depth % bits_per_word bits left over. In bitwise arithmetic:
-	 *
-	 * bits_per_word = 1 << shift
-	 * depth / bits_per_word = depth >> shift
-	 * depth % bits_per_word = depth & ((1 << shift) - 1)
-	 *
-	 * Each word can be limited to sbq->min_shallow_depth bits.
-	 */
-	shallow_depth = min(1U << sbq->sb.shift, sbq->min_shallow_depth);
-	depth = ((depth >> sbq->sb.shift) * shallow_depth +
-		 min(depth & ((1U << sbq->sb.shift) - 1), shallow_depth));
-	wake_batch = clamp_t(unsigned int, depth / SBQ_WAIT_QUEUES, 1,
-			     SBQ_WAKE_BATCH);
-
-	return wake_batch;
+	return clamp_t(unsigned int,
+		       min(depth, sbq->min_shallow_depth) / SBQ_WAIT_QUEUES,
+		       1, SBQ_WAKE_BATCH);
 }
 
 int sbitmap_queue_init_node(struct sbitmap_queue *sbq, unsigned int depth,
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 2/2] lib/sbitmap: make sbitmap_get_shallow() internal
  2025-08-05  7:37 [PATCH v3 0/2] lib/sbitmap: convert shallow_depth from one word to the whole sbitmap Yu Kuai
  2025-08-05  7:37 ` [PATCH v3 1/2] " Yu Kuai
@ 2025-08-05  7:37 ` Yu Kuai
  2025-08-05 15:35   ` Bart Van Assche
  1 sibling, 1 reply; 8+ messages in thread
From: Yu Kuai @ 2025-08-05  7:37 UTC (permalink / raw)
  To: yukuai3, axboe, akpm, ming.lei, dlemoal, jack
  Cc: linux-block, linux-kernel, yukuai1, yi.zhang, yangerkun,
	johnny.chenyi

From: Yu Kuai <yukuai3@huawei.com>

Because it's only used in sbitmap.c

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Jan Kara <jack@suse.cz>
---
 include/linux/sbitmap.h | 17 -----------------
 lib/sbitmap.c           | 18 ++++++++++++++++--
 2 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h
index 4adf4b364fcd..ffb9907c7070 100644
--- a/include/linux/sbitmap.h
+++ b/include/linux/sbitmap.h
@@ -209,23 +209,6 @@ void sbitmap_resize(struct sbitmap *sb, unsigned int depth);
  */
 int sbitmap_get(struct sbitmap *sb);
 
-/**
- * sbitmap_get_shallow() - Try to allocate a free bit from a &struct sbitmap,
- * limiting the depth used from each word.
- * @sb: Bitmap to allocate from.
- * @shallow_depth: The maximum number of bits to allocate from the bitmap.
- *
- * This rather specific operation allows for having multiple users with
- * different allocation limits. E.g., there can be a high-priority class that
- * uses sbitmap_get() and a low-priority class that uses sbitmap_get_shallow()
- * with a @shallow_depth of (sb->depth >> 1). Then, the low-priority
- * class can only allocate half of the total bits in the bitmap, preventing it
- * from starving out the high-priority class.
- *
- * Return: Non-negative allocated bit number if successful, -1 otherwise.
- */
-int sbitmap_get_shallow(struct sbitmap *sb, unsigned long shallow_depth);
-
 /**
  * sbitmap_any_bit_set() - Check for a set bit in a &struct sbitmap.
  * @sb: Bitmap to check.
diff --git a/lib/sbitmap.c b/lib/sbitmap.c
index 89be98859d5a..4d91028153bc 100644
--- a/lib/sbitmap.c
+++ b/lib/sbitmap.c
@@ -306,7 +306,22 @@ static int __sbitmap_get_shallow(struct sbitmap *sb,
 	return sbitmap_find_bit(sb, shallow_depth, index, alloc_hint, true);
 }
 
-int sbitmap_get_shallow(struct sbitmap *sb, unsigned long shallow_depth)
+/**
+ * sbitmap_get_shallow() - Try to allocate a free bit from a &struct sbitmap,
+ * limiting the depth used from each word.
+ * @sb: Bitmap to allocate from.
+ * @shallow_depth: The maximum number of bits to allocate from the bitmap.
+ *
+ * This rather specific operation allows for having multiple users with
+ * different allocation limits. E.g., there can be a high-priority class that
+ * uses sbitmap_get() and a low-priority class that uses sbitmap_get_shallow()
+ * with a @shallow_depth of (sb->depth >> 1). Then, the low-priority
+ * class can only allocate half of the total bits in the bitmap, preventing it
+ * from starving out the high-priority class.
+ *
+ * Return: Non-negative allocated bit number if successful, -1 otherwise.
+ */
+static int sbitmap_get_shallow(struct sbitmap *sb, unsigned long shallow_depth)
 {
 	int nr;
 	unsigned int hint, depth;
@@ -321,7 +336,6 @@ int sbitmap_get_shallow(struct sbitmap *sb, unsigned long shallow_depth)
 
 	return nr;
 }
-EXPORT_SYMBOL_GPL(sbitmap_get_shallow);
 
 bool sbitmap_any_bit_set(const struct sbitmap *sb)
 {
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 2/2] lib/sbitmap: make sbitmap_get_shallow() internal
  2025-08-05  7:37 ` [PATCH v3 2/2] lib/sbitmap: make sbitmap_get_shallow() internal Yu Kuai
@ 2025-08-05 15:35   ` Bart Van Assche
  0 siblings, 0 replies; 8+ messages in thread
From: Bart Van Assche @ 2025-08-05 15:35 UTC (permalink / raw)
  To: Yu Kuai, yukuai3, axboe, akpm, ming.lei, dlemoal, jack
  Cc: linux-block, linux-kernel, yi.zhang, yangerkun, johnny.chenyi

On 8/5/25 12:37 AM, Yu Kuai wrote:
> Because it's only used in sbitmap.c

Reviewed-by: Bart Van Assche <bvanassche@acm.org>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 1/2] lib/sbitmap: convert shallow_depth from one word to the whole sbitmap
  2025-08-05  7:37 ` [PATCH v3 1/2] " Yu Kuai
@ 2025-08-06  9:41   ` kernel test robot
  2025-08-07  1:30     ` Yu Kuai
  0 siblings, 1 reply; 8+ messages in thread
From: kernel test robot @ 2025-08-06  9:41 UTC (permalink / raw)
  To: Yu Kuai, yukuai3, axboe, akpm, ming.lei, dlemoal, jack
  Cc: oe-kbuild-all, linux-block, linux-kernel, yukuai1, yi.zhang,
	yangerkun, johnny.chenyi

Hi Yu,

kernel test robot noticed the following build errors:

[auto build test ERROR on axboe-block/for-next]
[also build test ERROR on linus/master v6.16 next-20250806]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Yu-Kuai/lib-sbitmap-convert-shallow_depth-from-one-word-to-the-whole-sbitmap/20250806-100430
base:   https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-next
patch link:    https://lore.kernel.org/r/20250805073748.606294-2-yukuai1%40huaweicloud.com
patch subject: [PATCH v3 1/2] lib/sbitmap: convert shallow_depth from one word to the whole sbitmap
config: sparc-randconfig-001-20250806 (https://download.01.org/0day-ci/archive/20250806/202508061722.0vTVFHLe-lkp@intel.com/config)
compiler: sparc-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250806/202508061722.0vTVFHLe-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202508061722.0vTVFHLe-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from ./arch/sparc/include/generated/asm/div64.h:1,
                    from include/linux/math.h:6,
                    from include/linux/kernel.h:27,
                    from include/linux/cpumask.h:11,
                    from arch/sparc/include/asm/smp_32.h:15,
                    from arch/sparc/include/asm/smp.h:7,
                    from arch/sparc/include/asm/switch_to_32.h:5,
                    from arch/sparc/include/asm/switch_to.h:7,
                    from arch/sparc/include/asm/ptrace.h:120,
                    from arch/sparc/include/asm/thread_info_32.h:19,
                    from arch/sparc/include/asm/thread_info.h:7,
                    from include/linux/thread_info.h:60,
                    from arch/sparc/include/asm/current.h:15,
                    from include/linux/sched.h:12,
                    from lib/sbitmap.c:7:
   lib/sbitmap.c: In function '__map_depth_with_shallow':
   include/asm-generic/div64.h:183:35: warning: comparison of distinct pointer types lacks a cast
     183 |         (void)(((typeof((n)) *)0) == ((uint64_t *)0));  \
         |                                   ^~
   lib/sbitmap.c:222:20: note: in expansion of macro 'do_div'
     222 |         reminder = do_div(shallow_word_depth, sb->depth);
         |                    ^~~~~~
   In file included from arch/sparc/include/asm/bug.h:6,
                    from include/linux/bug.h:5,
                    from include/linux/thread_info.h:13,
                    from arch/sparc/include/asm/current.h:15,
                    from include/linux/sched.h:12,
                    from lib/sbitmap.c:7:
>> include/asm-generic/div64.h:195:32: warning: right shift count >= width of type [-Wshift-count-overflow]
     195 |         } else if (likely(((n) >> 32) == 0)) {          \
         |                                ^~
   include/linux/compiler.h:76:45: note: in definition of macro 'likely'
      76 | # define likely(x)      __builtin_expect(!!(x), 1)
         |                                             ^
   lib/sbitmap.c:222:20: note: in expansion of macro 'do_div'
     222 |         reminder = do_div(shallow_word_depth, sb->depth);
         |                    ^~~~~~
   In file included from ./arch/sparc/include/generated/asm/div64.h:1,
                    from include/linux/math.h:6,
                    from include/linux/kernel.h:27,
                    from include/linux/cpumask.h:11,
                    from arch/sparc/include/asm/smp_32.h:15,
                    from arch/sparc/include/asm/smp.h:7,
                    from arch/sparc/include/asm/switch_to_32.h:5,
                    from arch/sparc/include/asm/switch_to.h:7,
                    from arch/sparc/include/asm/ptrace.h:120,
                    from arch/sparc/include/asm/thread_info_32.h:19,
                    from arch/sparc/include/asm/thread_info.h:7,
                    from include/linux/thread_info.h:60,
                    from arch/sparc/include/asm/current.h:15,
                    from include/linux/sched.h:12,
                    from lib/sbitmap.c:7:
>> include/asm-generic/div64.h:199:36: error: passing argument 1 of '__div64_32' from incompatible pointer type [-Werror=incompatible-pointer-types]
     199 |                 __rem = __div64_32(&(n), __base);       \
         |                                    ^~~~
         |                                    |
         |                                    unsigned int *
   lib/sbitmap.c:222:20: note: in expansion of macro 'do_div'
     222 |         reminder = do_div(shallow_word_depth, sb->depth);
         |                    ^~~~~~
   include/asm-generic/div64.h:174:38: note: expected 'uint64_t *' {aka 'long long unsigned int *'} but argument is of type 'unsigned int *'
     174 | extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
         |                            ~~~~~~~~~~^~~~~~~~
   cc1: some warnings being treated as errors


vim +/__div64_32 +199 include/asm-generic/div64.h

^1da177e4c3f415 Linus Torvalds     2005-04-16  176  
^1da177e4c3f415 Linus Torvalds     2005-04-16  177  /* The unnecessary pointer compare is there
^1da177e4c3f415 Linus Torvalds     2005-04-16  178   * to check for type safety (n must be 64bit)
^1da177e4c3f415 Linus Torvalds     2005-04-16  179   */
^1da177e4c3f415 Linus Torvalds     2005-04-16  180  # define do_div(n,base) ({				\
^1da177e4c3f415 Linus Torvalds     2005-04-16  181  	uint32_t __base = (base);			\
^1da177e4c3f415 Linus Torvalds     2005-04-16  182  	uint32_t __rem;					\
^1da177e4c3f415 Linus Torvalds     2005-04-16  183  	(void)(((typeof((n)) *)0) == ((uint64_t *)0));	\
911918aa7ef6f86 Nicolas Pitre      2015-11-02  184  	if (__builtin_constant_p(__base) &&		\
911918aa7ef6f86 Nicolas Pitre      2015-11-02  185  	    is_power_of_2(__base)) {			\
911918aa7ef6f86 Nicolas Pitre      2015-11-02  186  		__rem = (n) & (__base - 1);		\
911918aa7ef6f86 Nicolas Pitre      2015-11-02  187  		(n) >>= ilog2(__base);			\
c747ce4706190ef Geert Uytterhoeven 2021-08-11  188  	} else if (__builtin_constant_p(__base) &&	\
461a5e51060c93f Nicolas Pitre      2015-10-30  189  		   __base != 0) {			\
461a5e51060c93f Nicolas Pitre      2015-10-30  190  		uint32_t __res_lo, __n_lo = (n);	\
461a5e51060c93f Nicolas Pitre      2015-10-30  191  		(n) = __div64_const32(n, __base);	\
461a5e51060c93f Nicolas Pitre      2015-10-30  192  		/* the remainder can be computed with 32-bit regs */ \
461a5e51060c93f Nicolas Pitre      2015-10-30  193  		__res_lo = (n);				\
461a5e51060c93f Nicolas Pitre      2015-10-30  194  		__rem = __n_lo - __res_lo * __base;	\
911918aa7ef6f86 Nicolas Pitre      2015-11-02 @195  	} else if (likely(((n) >> 32) == 0)) {		\
^1da177e4c3f415 Linus Torvalds     2005-04-16  196  		__rem = (uint32_t)(n) % __base;		\
^1da177e4c3f415 Linus Torvalds     2005-04-16  197  		(n) = (uint32_t)(n) / __base;		\
c747ce4706190ef Geert Uytterhoeven 2021-08-11  198  	} else {					\
^1da177e4c3f415 Linus Torvalds     2005-04-16 @199  		__rem = __div64_32(&(n), __base);	\
c747ce4706190ef Geert Uytterhoeven 2021-08-11  200  	}						\
^1da177e4c3f415 Linus Torvalds     2005-04-16  201  	__rem;						\
^1da177e4c3f415 Linus Torvalds     2005-04-16  202   })
^1da177e4c3f415 Linus Torvalds     2005-04-16  203  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 1/2] lib/sbitmap: convert shallow_depth from one word to the whole sbitmap
  2025-08-06  9:41   ` kernel test robot
@ 2025-08-07  1:30     ` Yu Kuai
  2025-08-07  2:19       ` Jens Axboe
  2025-08-11  8:55       ` Geert Uytterhoeven
  0 siblings, 2 replies; 8+ messages in thread
From: Yu Kuai @ 2025-08-07  1:30 UTC (permalink / raw)
  To: kernel test robot, Yu Kuai, axboe, akpm, ming.lei, dlemoal, jack
  Cc: oe-kbuild-all, linux-block, linux-kernel, yi.zhang, yangerkun,
	johnny.chenyi, yukuai (C)

Hi,

在 2025/08/06 17:41, kernel test robot 写道:
> All error/warnings (new ones prefixed by >>):
> 
>     In file included from ./arch/sparc/include/generated/asm/div64.h:1,
>                      from include/linux/math.h:6,
>                      from include/linux/kernel.h:27,
>                      from include/linux/cpumask.h:11,
>                      from arch/sparc/include/asm/smp_32.h:15,
>                      from arch/sparc/include/asm/smp.h:7,
>                      from arch/sparc/include/asm/switch_to_32.h:5,
>                      from arch/sparc/include/asm/switch_to.h:7,
>                      from arch/sparc/include/asm/ptrace.h:120,
>                      from arch/sparc/include/asm/thread_info_32.h:19,
>                      from arch/sparc/include/asm/thread_info.h:7,
>                      from include/linux/thread_info.h:60,
>                      from arch/sparc/include/asm/current.h:15,
>                      from include/linux/sched.h:12,
>                      from lib/sbitmap.c:7:
>     lib/sbitmap.c: In function '__map_depth_with_shallow':
>     include/asm-generic/div64.h:183:35: warning: comparison of distinct pointer types lacks a cast
>       183 |         (void)(((typeof((n)) *)0) == ((uint64_t *)0));  \
>           |                                   ^~
>     lib/sbitmap.c:222:20: note: in expansion of macro 'do_div'
>       222 |         reminder = do_div(shallow_word_depth, sb->depth);
>           |                    ^~~~~~

/* The unnecessary pointer compare is there
  * to check for type safety (n must be 64bit)
  */
# define do_div(n,base) ({

I didn't notice that under specific arch, do_div() will require the fist
paramater to be 64bit.

I'll wait a bit longer for people to review the solution before I send a
new version.

Thanks,
Kuai


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 1/2] lib/sbitmap: convert shallow_depth from one word to the whole sbitmap
  2025-08-07  1:30     ` Yu Kuai
@ 2025-08-07  2:19       ` Jens Axboe
  2025-08-11  8:55       ` Geert Uytterhoeven
  1 sibling, 0 replies; 8+ messages in thread
From: Jens Axboe @ 2025-08-07  2:19 UTC (permalink / raw)
  To: Yu Kuai, kernel test robot, akpm, ming.lei, dlemoal, jack
  Cc: oe-kbuild-all, linux-block, linux-kernel, yi.zhang, yangerkun,
	johnny.chenyi, yukuai (C)

On 8/6/25 7:30 PM, Yu Kuai wrote:
> Hi,
> 
> ? 2025/08/06 17:41, kernel test robot ??:
>> All error/warnings (new ones prefixed by >>):
>>
>>     In file included from ./arch/sparc/include/generated/asm/div64.h:1,
>>                      from include/linux/math.h:6,
>>                      from include/linux/kernel.h:27,
>>                      from include/linux/cpumask.h:11,
>>                      from arch/sparc/include/asm/smp_32.h:15,
>>                      from arch/sparc/include/asm/smp.h:7,
>>                      from arch/sparc/include/asm/switch_to_32.h:5,
>>                      from arch/sparc/include/asm/switch_to.h:7,
>>                      from arch/sparc/include/asm/ptrace.h:120,
>>                      from arch/sparc/include/asm/thread_info_32.h:19,
>>                      from arch/sparc/include/asm/thread_info.h:7,
>>                      from include/linux/thread_info.h:60,
>>                      from arch/sparc/include/asm/current.h:15,
>>                      from include/linux/sched.h:12,
>>                      from lib/sbitmap.c:7:
>>     lib/sbitmap.c: In function '__map_depth_with_shallow':
>>     include/asm-generic/div64.h:183:35: warning: comparison of distinct pointer types lacks a cast
>>       183 |         (void)(((typeof((n)) *)0) == ((uint64_t *)0));  \
>>           |                                   ^~
>>     lib/sbitmap.c:222:20: note: in expansion of macro 'do_div'
>>       222 |         reminder = do_div(shallow_word_depth, sb->depth);
>>           |                    ^~~~~~
> 
> /* The unnecessary pointer compare is there
>  * to check for type safety (n must be 64bit)
>  */
> # define do_div(n,base) ({
> 
> I didn't notice that under specific arch, do_div() will require the fist
> paramater to be 64bit.
> 
> I'll wait a bit longer for people to review the solution before I send a
> new version.

I think it looks good, so please do spin a new version with that fixed
as that's the only thing holding up the inclusion right now.

-- 
Jens Axboe

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 1/2] lib/sbitmap: convert shallow_depth from one word to the whole sbitmap
  2025-08-07  1:30     ` Yu Kuai
  2025-08-07  2:19       ` Jens Axboe
@ 2025-08-11  8:55       ` Geert Uytterhoeven
  1 sibling, 0 replies; 8+ messages in thread
From: Geert Uytterhoeven @ 2025-08-11  8:55 UTC (permalink / raw)
  To: Yu Kuai
  Cc: kernel test robot, axboe, akpm, ming.lei, dlemoal, jack,
	oe-kbuild-all, linux-block, linux-kernel, yi.zhang, yangerkun,
	johnny.chenyi, yukuai (C)

Hi Kuai,

On Thu, 7 Aug 2025 at 23:37, Yu Kuai <yukuai1@huaweicloud.com> wrote:
> 在 2025/08/06 17:41, kernel test robot 写道:
> > All error/warnings (new ones prefixed by >>):
> >
> >     In file included from ./arch/sparc/include/generated/asm/div64.h:1,
> >                      from include/linux/math.h:6,
> >                      from include/linux/kernel.h:27,
> >                      from include/linux/cpumask.h:11,
> >                      from arch/sparc/include/asm/smp_32.h:15,
> >                      from arch/sparc/include/asm/smp.h:7,
> >                      from arch/sparc/include/asm/switch_to_32.h:5,
> >                      from arch/sparc/include/asm/switch_to.h:7,
> >                      from arch/sparc/include/asm/ptrace.h:120,
> >                      from arch/sparc/include/asm/thread_info_32.h:19,
> >                      from arch/sparc/include/asm/thread_info.h:7,
> >                      from include/linux/thread_info.h:60,
> >                      from arch/sparc/include/asm/current.h:15,
> >                      from include/linux/sched.h:12,
> >                      from lib/sbitmap.c:7:
> >     lib/sbitmap.c: In function '__map_depth_with_shallow':
> >     include/asm-generic/div64.h:183:35: warning: comparison of distinct pointer types lacks a cast
> >       183 |         (void)(((typeof((n)) *)0) == ((uint64_t *)0));  \
> >           |                                   ^~
> >     lib/sbitmap.c:222:20: note: in expansion of macro 'do_div'
> >       222 |         reminder = do_div(shallow_word_depth, sb->depth);
> >           |                    ^~~~~~
>
> /* The unnecessary pointer compare is there
>   * to check for type safety (n must be 64bit)
>   */
> # define do_div(n,base) ({
>
> I didn't notice that under specific arch, do_div() will require the fist
> paramater to be 64bit.

do_div() is strictly meant for a 64-by-32 div/mod operation.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-08-11  8:55 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-05  7:37 [PATCH v3 0/2] lib/sbitmap: convert shallow_depth from one word to the whole sbitmap Yu Kuai
2025-08-05  7:37 ` [PATCH v3 1/2] " Yu Kuai
2025-08-06  9:41   ` kernel test robot
2025-08-07  1:30     ` Yu Kuai
2025-08-07  2:19       ` Jens Axboe
2025-08-11  8:55       ` Geert Uytterhoeven
2025-08-05  7:37 ` [PATCH v3 2/2] lib/sbitmap: make sbitmap_get_shallow() internal Yu Kuai
2025-08-05 15:35   ` Bart Van Assche

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).