History

lib/sbitmap: kill 'depth' from sbitmap_word

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.

Ming Lei committed 4 years ago

Commit 3301bc51 parent abfc4262 files · +24 −27Browse files

Unified · Split

2 files
  1. include/linux/sbitmap.h +10 −7
  2. lib/sbitmap.c +14 −20
include/linux/sbitmap.h+10−7
@@ -27,15 +27,10 @@ struct seq_file; · 26 unmodified lines
27 * struct sbitmap_word - Word in a &struct sbitmap.27 * struct sbitmap_word - Word in a &struct sbitmap.
28 */28 */
29struct sbitmap_word {29struct sbitmap_word {
30 /**
31 * @depth: Number of bits being used in @word/@cleared
32 */
33 unsigned long depth;
34
35 /**30 /**
36 * @word: word holding free bits31 * @word: word holding free bits
37 */32 */
38 unsigned long word ____cacheline_aligned_in_smp;33 unsigned long word;
39 34
40 /**35 /**
41 * @cleared: word holding cleared bits36 * @cleared: word holding cleared bits
@@ -164,6 +159,14 @@ struct sbitmap_queue { · 122 unmodified lines
164int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift,159int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift,
165 gfp_t flags, int node, bool round_robin, bool alloc_hint);160 gfp_t flags, int node, bool round_robin, bool alloc_hint);
166 161
162/* sbitmap internal helper */
163static inline unsigned int __map_depth(const struct sbitmap *sb, int index)
164{
165 if (index == sb->map_nr - 1)
166 return sb->depth - (index << sb->shift);
167 return 1U << sb->shift;
168}
169
167/**170/**
168 * sbitmap_free() - Free memory used by a &struct sbitmap.171 * sbitmap_free() - Free memory used by a &struct sbitmap.
169 * @sb: Bitmap to free.172 * @sb: Bitmap to free.
@@ -251,7 +254,7 @@ static inline void __sbitmap_for_each_set(struct sbitmap *sb, · 81 unmodified lines
251 while (scanned < sb->depth) {254 while (scanned < sb->depth) {
252 unsigned long word;255 unsigned long word;
253 unsigned int depth = min_t(unsigned int,256 unsigned int depth = min_t(unsigned int,
254 sb->map[index].depth - nr,257 __map_depth(sb, index) - nr,
255 sb->depth - scanned);258 sb->depth - scanned);
256 259
257 scanned += depth;260 scanned += depth;
lib/sbitmap.c+14−20
@@ -85,7 +85,6 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, · 84 unmodified lines
85 bool alloc_hint)85 bool alloc_hint)
86{86{
87 unsigned int bits_per_word;87 unsigned int bits_per_word;
88 unsigned int i;
89 88
90 if (shift < 0)89 if (shift < 0)
91 shift = sbitmap_calculate_shift(depth);90 shift = sbitmap_calculate_shift(depth);
@@ -117,10 +116,6 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, · 25 unmodified lines
117 return -ENOMEM;116 return -ENOMEM;
118 }117 }
119 118
120 for (i = 0; i < sb->map_nr; i++) {
121 sb->map[i].depth = min(depth, bits_per_word);
122 depth -= sb->map[i].depth;
123 }
124 return 0;119 return 0;
125}120}
126EXPORT_SYMBOL_GPL(sbitmap_init_node);121EXPORT_SYMBOL_GPL(sbitmap_init_node);
@@ -135,11 +130,6 @@ void sbitmap_resize(struct sbitmap *sb, unsigned int depth) · 8 unmodified lines
135 130
136 sb->depth = depth;131 sb->depth = depth;
137 sb->map_nr = DIV_ROUND_UP(sb->depth, bits_per_word);132 sb->map_nr = DIV_ROUND_UP(sb->depth, bits_per_word);
138
139 for (i = 0; i < sb->map_nr; i++) {
140 sb->map[i].depth = min(depth, bits_per_word);
141 depth -= sb->map[i].depth;
142 }
143}133}
144EXPORT_SYMBOL_GPL(sbitmap_resize);134EXPORT_SYMBOL_GPL(sbitmap_resize);
145 135
@@ -184,8 +174,8 @@ static int sbitmap_find_bit_in_index(struct sbitmap *sb, int index, · 38 unmodified lines
184 int nr;174 int nr;
185 175
186 do {176 do {
187 nr = __sbitmap_get_word(&map->word, map->depth, alloc_hint,177 nr = __sbitmap_get_word(&map->word, __map_depth(sb, index),
188 !sb->round_robin);178 alloc_hint, !sb->round_robin);
189 if (nr != -1)179 if (nr != -1)
190 break;180 break;
191 if (!sbitmap_deferred_clear(map))181 if (!sbitmap_deferred_clear(map))
@@ -257,7 +247,9 @@ static int __sbitmap_get_shallow(struct sbitmap *sb, · 65 unmodified lines
257 for (i = 0; i < sb->map_nr; i++) {247 for (i = 0; i < sb->map_nr; i++) {
258again:248again:
259 nr = __sbitmap_get_word(&sb->map[index].word,249 nr = __sbitmap_get_word(&sb->map[index].word,
260 min(sb->map[index].depth, shallow_depth),250 min_t(unsigned int,
251 __map_depth(sb, index),
252 shallow_depth),
261 SB_NR_TO_BIT(sb, alloc_hint), true);253 SB_NR_TO_BIT(sb, alloc_hint), true);
262 if (nr != -1) {254 if (nr != -1) {
263 nr += index << sb->shift;255 nr += index << sb->shift;
@@ -315,11 +307,12 @@ static unsigned int __sbitmap_weight(const struct sbitmap *sb, bool set) · 51 unmodified lines
315 307
316 for (i = 0; i < sb->map_nr; i++) {308 for (i = 0; i < sb->map_nr; i++) {
317 const struct sbitmap_word *word = &sb->map[i];309 const struct sbitmap_word *word = &sb->map[i];
310 unsigned int word_depth = __map_depth(sb, i);
318 311
319 if (set)312 if (set)
320 weight += bitmap_weight(&word->word, word->depth);313 weight += bitmap_weight(&word->word, word_depth);
321 else314 else
322 weight += bitmap_weight(&word->cleared, word->depth);315 weight += bitmap_weight(&word->cleared, word_depth);
323 }316 }
324 return weight;317 return weight;
325}318}
@@ -367,7 +360,7 @@ void sbitmap_bitmap_show(struct sbitmap *sb, struct seq_file *m) · 41 unmodified lines
367 for (i = 0; i < sb->map_nr; i++) {360 for (i = 0; i < sb->map_nr; i++) {
368 unsigned long word = READ_ONCE(sb->map[i].word);361 unsigned long word = READ_ONCE(sb->map[i].word);
369 unsigned long cleared = READ_ONCE(sb->map[i].cleared);362 unsigned long cleared = READ_ONCE(sb->map[i].cleared);
370 unsigned int word_bits = READ_ONCE(sb->map[i].depth);363 unsigned int word_bits = __map_depth(sb, i);
371 364
372 word &= ~cleared;365 word &= ~cleared;
373 366
@@ -531,15 +524,16 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags, · 157 unmodified lines
531 for (i = 0; i < sb->map_nr; i++) {524 for (i = 0; i < sb->map_nr; i++) {
532 struct sbitmap_word *map = &sb->map[index];525 struct sbitmap_word *map = &sb->map[index];
533 unsigned long get_mask;526 unsigned long get_mask;
527 unsigned int map_depth = __map_depth(sb, index);
534 528
535 sbitmap_deferred_clear(map);529 sbitmap_deferred_clear(map);
536 if (map->word == (1UL << (map->depth - 1)) - 1)530 if (map->word == (1UL << (map_depth - 1)) - 1)
537 continue;531 continue;
538 532
539 nr = find_first_zero_bit(&map->word, map->depth);533 nr = find_first_zero_bit(&map->word, map_depth);
540 if (nr + nr_tags <= map->depth) {534 if (nr + nr_tags <= map_depth) {
541 atomic_long_t *ptr = (atomic_long_t *) &map->word;535 atomic_long_t *ptr = (atomic_long_t *) &map->word;
542 int map_tags = min_t(int, nr_tags, map->depth);536 int map_tags = min_t(int, nr_tags, map_depth);
543 unsigned long val, ret;537 unsigned long val, ret;
544 538
545 get_mask = ((1UL << map_tags) - 1) << nr;539 get_mask = ((1UL << map_tags) - 1) << nr;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t