2020#include <linux/sbitmap.h>
2121#include <linux/seq_file.h>
2222
23+ /*
24+ * See if we have deferred clears that we can batch move
25+ */
26+ static inline bool sbitmap_deferred_clear (struct sbitmap * sb , int index )
27+ {
28+ unsigned long mask , val ;
29+ unsigned long __maybe_unused flags ;
30+ bool ret = false;
31+
32+ /* Silence bogus lockdep warning */
33+ #if defined(CONFIG_LOCKDEP )
34+ local_irq_save (flags );
35+ #endif
36+ spin_lock (& sb -> map [index ].swap_lock );
37+
38+ if (!sb -> map [index ].cleared )
39+ goto out_unlock ;
40+
41+ /*
42+ * First get a stable cleared mask, setting the old mask to 0.
43+ */
44+ do {
45+ mask = sb -> map [index ].cleared ;
46+ } while (cmpxchg (& sb -> map [index ].cleared , mask , 0 ) != mask );
47+
48+ /*
49+ * Now clear the masked bits in our free word
50+ */
51+ do {
52+ val = sb -> map [index ].word ;
53+ } while (cmpxchg (& sb -> map [index ].word , val , val & ~mask ) != val );
54+
55+ ret = true;
56+ out_unlock :
57+ spin_unlock (& sb -> map [index ].swap_lock );
58+ #if defined(CONFIG_LOCKDEP )
59+ local_irq_restore (flags );
60+ #endif
61+ return ret ;
62+ }
63+
2364int sbitmap_init_node (struct sbitmap * sb , unsigned int depth , int shift ,
2465 gfp_t flags , int node )
2566{
@@ -70,6 +111,9 @@ void sbitmap_resize(struct sbitmap *sb, unsigned int depth)
70111 unsigned int bits_per_word = 1U << sb -> shift ;
71112 unsigned int i ;
72113
114+ for (i = 0 ; i < sb -> map_nr ; i ++ )
115+ sbitmap_deferred_clear (sb , i );
116+
73117 sb -> depth = depth ;
74118 sb -> map_nr = DIV_ROUND_UP (sb -> depth , bits_per_word );
75119
@@ -112,47 +156,6 @@ static int __sbitmap_get_word(unsigned long *word, unsigned long depth,
112156 return nr ;
113157}
114158
115- /*
116- * See if we have deferred clears that we can batch move
117- */
118- static inline bool sbitmap_deferred_clear (struct sbitmap * sb , int index )
119- {
120- unsigned long mask , val ;
121- unsigned long __maybe_unused flags ;
122- bool ret = false;
123-
124- /* Silence bogus lockdep warning */
125- #if defined(CONFIG_LOCKDEP )
126- local_irq_save (flags );
127- #endif
128- spin_lock (& sb -> map [index ].swap_lock );
129-
130- if (!sb -> map [index ].cleared )
131- goto out_unlock ;
132-
133- /*
134- * First get a stable cleared mask, setting the old mask to 0.
135- */
136- do {
137- mask = sb -> map [index ].cleared ;
138- } while (cmpxchg (& sb -> map [index ].cleared , mask , 0 ) != mask );
139-
140- /*
141- * Now clear the masked bits in our free word
142- */
143- do {
144- val = sb -> map [index ].word ;
145- } while (cmpxchg (& sb -> map [index ].word , val , val & ~mask ) != val );
146-
147- ret = true;
148- out_unlock :
149- spin_unlock (& sb -> map [index ].swap_lock );
150- #if defined(CONFIG_LOCKDEP )
151- local_irq_restore (flags );
152- #endif
153- return ret ;
154- }
155-
156159static int sbitmap_find_bit_in_index (struct sbitmap * sb , int index ,
157160 unsigned int alloc_hint , bool round_robin )
158161{
@@ -215,6 +218,7 @@ int sbitmap_get_shallow(struct sbitmap *sb, unsigned int alloc_hint,
215218 index = SB_NR_TO_INDEX (sb , alloc_hint );
216219
217220 for (i = 0 ; i < sb -> map_nr ; i ++ ) {
221+ again :
218222 nr = __sbitmap_get_word (& sb -> map [index ].word ,
219223 min (sb -> map [index ].depth , shallow_depth ),
220224 SB_NR_TO_BIT (sb , alloc_hint ), true);
@@ -223,6 +227,9 @@ int sbitmap_get_shallow(struct sbitmap *sb, unsigned int alloc_hint,
223227 break ;
224228 }
225229
230+ if (sbitmap_deferred_clear (sb , index ))
231+ goto again ;
232+
226233 /* Jump to next index. */
227234 index ++ ;
228235 alloc_hint = index << sb -> shift ;
@@ -242,7 +249,7 @@ bool sbitmap_any_bit_set(const struct sbitmap *sb)
242249 unsigned int i ;
243250
244251 for (i = 0 ; i < sb -> map_nr ; i ++ ) {
245- if (sb -> map [i ].word )
252+ if (sb -> map [i ].word & ~ sb -> map [ i ]. cleared )
246253 return true;
247254 }
248255 return false;
@@ -255,9 +262,10 @@ bool sbitmap_any_bit_clear(const struct sbitmap *sb)
255262
256263 for (i = 0 ; i < sb -> map_nr ; i ++ ) {
257264 const struct sbitmap_word * word = & sb -> map [i ];
265+ unsigned long mask = word -> word & ~word -> cleared ;
258266 unsigned long ret ;
259267
260- ret = find_first_zero_bit (& word -> word , word -> depth );
268+ ret = find_first_zero_bit (& mask , word -> depth );
261269 if (ret < word -> depth )
262270 return true;
263271 }
0 commit comments