diff options
author | Yury Norov <yury.norov@gmail.com> | 2023-12-11 18:27:17 -0800 |
---|---|---|
committer | Yury Norov <yury.norov@gmail.com> | 2023-12-16 08:42:57 -0800 |
commit | 0af7b0df61f906c57568b8730df70058820a7613 (patch) | |
tree | 2e09f5eddb65dab48526e7e8dd23ac47b0193f56 | |
parent | 9297e20670743257f6c3fe7ebd6be5802b1dc8c7 (diff) | |
download | linux-0af7b0df61f906c57568b8730df70058820a7613.tar.gz linux-0af7b0df61f906c57568b8730df70058820a7613.tar.xz |
lib/sbitmap; optimize __sbitmap_get_word() by using find_and_set_bit()
__sbitmap_get_word() opencodes either find_and_set_bit_wrap(), or
find_and_set_next_bit() depending on wrap parameter. Simplify it by using
atomic find_bit() API.
While here, simplify sbitmap_find_bit_in_word(), which calls it.
CC: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Yury Norov <yury.norov@gmail.com>
Reviewed-by: Jan Kara <jack@suse.cz>
-rw-r--r-- | lib/sbitmap.c | 46 |
1 files changed, 9 insertions, 37 deletions
diff --git a/lib/sbitmap.c b/lib/sbitmap.c index d0a5081dfd12..8ecd830ba9e8 100644 --- a/lib/sbitmap.c +++ b/lib/sbitmap.c @@ -133,38 +133,13 @@ void sbitmap_resize(struct sbitmap *sb, unsigned int depth) } EXPORT_SYMBOL_GPL(sbitmap_resize); -static int __sbitmap_get_word(unsigned long *word, unsigned long depth, +static inline int __sbitmap_get_word(unsigned long *word, unsigned long depth, unsigned int hint, bool wrap) { - int nr; - - /* don't wrap if starting from 0 */ - wrap = wrap && hint; - - while (1) { - nr = find_next_zero_bit(word, depth, hint); - if (unlikely(nr >= depth)) { - /* - * We started with an offset, and we didn't reset the - * offset to 0 in a failure case, so start from 0 to - * exhaust the map. - */ - if (hint && wrap) { - hint = 0; - continue; - } - return -1; - } + if (wrap) + return find_and_set_bit_wrap_lock(word, depth, hint); - if (!test_and_set_bit_lock(nr, word)) - break; - - hint = nr + 1; - if (hint >= depth - 1) - hint = 0; - } - - return nr; + return find_and_set_next_bit_lock(word, depth, hint); } static int sbitmap_find_bit_in_word(struct sbitmap_word *map, @@ -175,15 +150,12 @@ static int sbitmap_find_bit_in_word(struct sbitmap_word *map, int nr; do { - nr = __sbitmap_get_word(&map->word, depth, - alloc_hint, wrap); - if (nr != -1) - break; - if (!sbitmap_deferred_clear(map)) - break; - } while (1); + nr = __sbitmap_get_word(&map->word, depth, alloc_hint, wrap); + if (nr < depth) + return nr; + } while (sbitmap_deferred_clear(map)); - return nr; + return -1; } static int sbitmap_find_bit(struct sbitmap *sb, |