Skip to content

Commit 279a256

Browse files
committed
lib/sbitmap: kill 'depth' from sbitmap_word
jira LE-4066 Rebuild_History Non-Buildable kernel-4.18.0-553.72.1.el8_10 commit-author Ming Lei <ming.lei@redhat.com> commit 3301bc5 Only the last sbitmap_word can have different depth, and all the others must have same depth of 1U << sb->shift, so not necessary to store it in sbitmap_word, and it can be retrieved easily and efficiently by adding one internal helper of __map_depth(sb, index). Remove 'depth' field from sbitmap_word, then the annotation of ____cacheline_aligned_in_smp for 'word' isn't needed any more. Not see performance effect when running high parallel IOPS test on null_blk. This way saves us one cacheline(usually 64 words) per each sbitmap_word. Cc: Martin Wilck <martin.wilck@suse.com> Signed-off-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Martin Wilck <mwilck@suse.com> Reviewed-by: John Garry <john.garry@huawei.com> Link: https://lore.kernel.org/r/20220110072945.347535-1-ming.lei@redhat.com Signed-off-by: Jens Axboe <axboe@kernel.dk> (cherry picked from commit 3301bc5) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 2cec149 commit 279a256

File tree

2 files changed

+24
-27
lines changed

2 files changed

+24
-27
lines changed

include/linux/sbitmap.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,10 @@ struct seq_file;
2929
* struct sbitmap_word - Word in a &struct sbitmap.
3030
*/
3131
struct sbitmap_word {
32-
/**
33-
* @depth: Number of bits being used in @word/@cleared
34-
*/
35-
unsigned long depth;
36-
3732
/**
3833
* @word: word holding free bits
3934
*/
40-
unsigned long word ____cacheline_aligned_in_smp;
35+
unsigned long word;
4136

4237
/**
4338
* @cleared: word holding cleared bits
@@ -179,6 +174,14 @@ struct sbitmap_queue {
179174
int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift,
180175
gfp_t flags, int node, bool round_robin, bool alloc_hint);
181176

177+
/* sbitmap internal helper */
178+
static inline unsigned int __map_depth(const struct sbitmap *sb, int index)
179+
{
180+
if (index == sb->map_nr - 1)
181+
return sb->depth - (index << sb->shift);
182+
return 1U << sb->shift;
183+
}
184+
182185
/**
183186
* sbitmap_free() - Free memory used by a &struct sbitmap.
184187
* @sb: Bitmap to free.
@@ -276,7 +279,7 @@ static inline void __sbitmap_for_each_set(struct sbitmap *sb,
276279
while (scanned < sb->depth) {
277280
unsigned long word;
278281
unsigned int depth = min_t(unsigned int,
279-
sb->map[index].depth - nr,
282+
__map_depth(sb, index) - nr,
280283
sb->depth - scanned);
281284

282285
scanned += depth;

lib/sbitmap.c

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift,
101101
bool alloc_hint)
102102
{
103103
unsigned int bits_per_word;
104-
unsigned int i;
105104

106105
if (shift < 0)
107106
shift = sbitmap_calculate_shift(depth);
@@ -139,10 +138,6 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift,
139138
*SB_ALLOC_HINT_PTR(sb) = NULL;
140139
}
141140

142-
for (i = 0; i < sb->map_nr; i++) {
143-
sb->map[i].depth = min(depth, bits_per_word);
144-
depth -= sb->map[i].depth;
145-
}
146141
return 0;
147142
}
148143
EXPORT_SYMBOL_GPL(sbitmap_init_node);
@@ -157,11 +152,6 @@ void sbitmap_resize(struct sbitmap *sb, unsigned int depth)
157152

158153
sb->depth = depth;
159154
sb->map_nr = DIV_ROUND_UP(sb->depth, bits_per_word);
160-
161-
for (i = 0; i < sb->map_nr; i++) {
162-
sb->map[i].depth = min(depth, bits_per_word);
163-
depth -= sb->map[i].depth;
164-
}
165155
}
166156
EXPORT_SYMBOL_GPL(sbitmap_resize);
167157

@@ -204,8 +194,8 @@ static int sbitmap_find_bit_in_index(struct sbitmap *sb, int index,
204194
int nr;
205195

206196
do {
207-
nr = __sbitmap_get_word(&map->word, map->depth, alloc_hint,
208-
!sb->round_robin);
197+
nr = __sbitmap_get_word(&map->word, __map_depth(sb, index),
198+
alloc_hint, !sb->round_robin);
209199
if (nr != -1)
210200
break;
211201
if (!sbitmap_deferred_clear(map))
@@ -278,7 +268,9 @@ static int __sbitmap_get_shallow(struct sbitmap *sb,
278268
for (i = 0; i < sb->map_nr; i++) {
279269
again:
280270
nr = __sbitmap_get_word(&sb->map[index].word,
281-
min(sb->map[index].depth, shallow_depth),
271+
min_t(unsigned int,
272+
__map_depth(sb, index),
273+
shallow_depth),
282274
SB_NR_TO_BIT(sb, alloc_hint), true);
283275
if (nr != -1) {
284276
nr += index << sb->shift;
@@ -337,11 +329,12 @@ static unsigned int __sbitmap_weight(const struct sbitmap *sb, bool set)
337329

338330
for (i = 0; i < sb->map_nr; i++) {
339331
const struct sbitmap_word *word = &sb->map[i];
332+
unsigned int word_depth = __map_depth(sb, i);
340333

341334
if (set)
342-
weight += bitmap_weight(&word->word, word->depth);
335+
weight += bitmap_weight(&word->word, word_depth);
343336
else
344-
weight += bitmap_weight(&word->cleared, word->depth);
337+
weight += bitmap_weight(&word->cleared, word_depth);
345338
}
346339
return weight;
347340
}
@@ -389,7 +382,7 @@ void sbitmap_bitmap_show(struct sbitmap *sb, struct seq_file *m)
389382
for (i = 0; i < sb->map_nr; i++) {
390383
unsigned long word = READ_ONCE(sb->map[i].word);
391384
unsigned long cleared = READ_ONCE(sb->map[i].cleared);
392-
unsigned int word_bits = READ_ONCE(sb->map[i].depth);
385+
unsigned int word_bits = __map_depth(sb, i);
393386

394387
word &= ~cleared;
395388

@@ -530,15 +523,16 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags,
530523
for (i = 0; i < sb->map_nr; i++) {
531524
struct sbitmap_word *map = &sb->map[index];
532525
unsigned long get_mask;
526+
unsigned int map_depth = __map_depth(sb, index);
533527

534528
sbitmap_deferred_clear(map);
535-
if (map->word == (1UL << (map->depth - 1)) - 1)
529+
if (map->word == (1UL << (map_depth - 1)) - 1)
536530
continue;
537531

538-
nr = find_first_zero_bit(&map->word, map->depth);
539-
if (nr + nr_tags <= map->depth) {
532+
nr = find_first_zero_bit(&map->word, map_depth);
533+
if (nr + nr_tags <= map_depth) {
540534
atomic_long_t *ptr = (atomic_long_t *) &map->word;
541-
int map_tags = min_t(int, nr_tags, map->depth);
535+
int map_tags = min_t(int, nr_tags, map_depth);
542536
unsigned long val, ret;
543537

544538
get_mask = ((1UL << map_tags) - 1) << nr;

0 commit comments

Comments
 (0)