* [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 [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
* [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 [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
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
all inboxes | Powered by JetHome®