Skip to content

Commit ed8cd2b

Browse files
committed
bitmap: Switch from inline to __always_inline
'inline' keyword is only a recommendation for compiler. If it decides to not inline bitmap functions, the whole small_const_nbits() machinery doesn't work. This is how a standard GCC 11.3.0 does for my x86_64 build now. This patch replaces 'inline' directive with unconditional '__always_inline' to make sure that there's always a chance for compile-time optimization. It doesn't change size of kernel image, according to bloat-o-meter. [[ Brian: split out from: Subject: [PATCH 1/3] bitmap: switch from inline to __always_inline https://lore.kernel.org/all/[email protected]/ But rewritten, as there were too many conflicts. ]] Co-developed-by: Brian Norris <[email protected]> Signed-off-by: Brian Norris <[email protected]> Reviewed-by: Kees Cook <[email protected]> Reviewed-by: Nathan Chancellor <[email protected]> Signed-off-by: Yury Norov <[email protected]>
1 parent fda1dd3 commit ed8cd2b

File tree

1 file changed

+76
-64
lines changed

1 file changed

+76
-64
lines changed

include/linux/bitmap.h

Lines changed: 76 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,12 @@ unsigned long bitmap_find_next_zero_area_off(unsigned long *map,
203203
* the bit offset of all zero areas this function finds is multiples of that
204204
* power of 2. A @align_mask of 0 means no alignment is required.
205205
*/
206-
static inline unsigned long
207-
bitmap_find_next_zero_area(unsigned long *map,
208-
unsigned long size,
209-
unsigned long start,
210-
unsigned int nr,
211-
unsigned long align_mask)
206+
static __always_inline
207+
unsigned long bitmap_find_next_zero_area(unsigned long *map,
208+
unsigned long size,
209+
unsigned long start,
210+
unsigned int nr,
211+
unsigned long align_mask)
212212
{
213213
return bitmap_find_next_zero_area_off(map, size, start, nr,
214214
align_mask, 0);
@@ -228,7 +228,7 @@ void bitmap_fold(unsigned long *dst, const unsigned long *orig,
228228

229229
#define bitmap_size(nbits) (ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE)
230230

231-
static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
231+
static __always_inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
232232
{
233233
unsigned int len = bitmap_size(nbits);
234234

@@ -238,7 +238,7 @@ static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
238238
memset(dst, 0, len);
239239
}
240240

241-
static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
241+
static __always_inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
242242
{
243243
unsigned int len = bitmap_size(nbits);
244244

@@ -248,8 +248,8 @@ static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
248248
memset(dst, 0xff, len);
249249
}
250250

251-
static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
252-
unsigned int nbits)
251+
static __always_inline
252+
void bitmap_copy(unsigned long *dst, const unsigned long *src, unsigned int nbits)
253253
{
254254
unsigned int len = bitmap_size(nbits);
255255

@@ -262,8 +262,8 @@ static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
262262
/*
263263
* Copy bitmap and clear tail bits in last word.
264264
*/
265-
static inline void bitmap_copy_clear_tail(unsigned long *dst,
266-
const unsigned long *src, unsigned int nbits)
265+
static __always_inline
266+
void bitmap_copy_clear_tail(unsigned long *dst, const unsigned long *src, unsigned int nbits)
267267
{
268268
bitmap_copy(dst, src, nbits);
269269
if (nbits % BITS_PER_LONG)
@@ -306,42 +306,46 @@ void bitmap_to_arr64(u64 *buf, const unsigned long *bitmap, unsigned int nbits);
306306
bitmap_copy_clear_tail((unsigned long *)(buf), (const unsigned long *)(bitmap), (nbits))
307307
#endif
308308

309-
static inline bool bitmap_and(unsigned long *dst, const unsigned long *src1,
310-
const unsigned long *src2, unsigned int nbits)
309+
static __always_inline
310+
bool bitmap_and(unsigned long *dst, const unsigned long *src1,
311+
const unsigned long *src2, unsigned int nbits)
311312
{
312313
if (small_const_nbits(nbits))
313314
return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0;
314315
return __bitmap_and(dst, src1, src2, nbits);
315316
}
316317

317-
static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
318-
const unsigned long *src2, unsigned int nbits)
318+
static __always_inline
319+
void bitmap_or(unsigned long *dst, const unsigned long *src1,
320+
const unsigned long *src2, unsigned int nbits)
319321
{
320322
if (small_const_nbits(nbits))
321323
*dst = *src1 | *src2;
322324
else
323325
__bitmap_or(dst, src1, src2, nbits);
324326
}
325327

326-
static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
327-
const unsigned long *src2, unsigned int nbits)
328+
static __always_inline
329+
void bitmap_xor(unsigned long *dst, const unsigned long *src1,
330+
const unsigned long *src2, unsigned int nbits)
328331
{
329332
if (small_const_nbits(nbits))
330333
*dst = *src1 ^ *src2;
331334
else
332335
__bitmap_xor(dst, src1, src2, nbits);
333336
}
334337

335-
static inline bool bitmap_andnot(unsigned long *dst, const unsigned long *src1,
336-
const unsigned long *src2, unsigned int nbits)
338+
static __always_inline
339+
bool bitmap_andnot(unsigned long *dst, const unsigned long *src1,
340+
const unsigned long *src2, unsigned int nbits)
337341
{
338342
if (small_const_nbits(nbits))
339343
return (*dst = *src1 & ~(*src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
340344
return __bitmap_andnot(dst, src1, src2, nbits);
341345
}
342346

343-
static inline void bitmap_complement(unsigned long *dst, const unsigned long *src,
344-
unsigned int nbits)
347+
static __always_inline
348+
void bitmap_complement(unsigned long *dst, const unsigned long *src, unsigned int nbits)
345349
{
346350
if (small_const_nbits(nbits))
347351
*dst = ~(*src);
@@ -356,8 +360,8 @@ static inline void bitmap_complement(unsigned long *dst, const unsigned long *sr
356360
#endif
357361
#define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1)
358362

359-
static inline bool bitmap_equal(const unsigned long *src1,
360-
const unsigned long *src2, unsigned int nbits)
363+
static __always_inline
364+
bool bitmap_equal(const unsigned long *src1, const unsigned long *src2, unsigned int nbits)
361365
{
362366
if (small_const_nbits(nbits))
363367
return !((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
@@ -376,45 +380,45 @@ static inline bool bitmap_equal(const unsigned long *src1,
376380
*
377381
* Returns: True if (*@src1 | *@src2) == *@src3, false otherwise
378382
*/
379-
static inline bool bitmap_or_equal(const unsigned long *src1,
380-
const unsigned long *src2,
381-
const unsigned long *src3,
382-
unsigned int nbits)
383+
static __always_inline
384+
bool bitmap_or_equal(const unsigned long *src1, const unsigned long *src2,
385+
const unsigned long *src3, unsigned int nbits)
383386
{
384387
if (!small_const_nbits(nbits))
385388
return __bitmap_or_equal(src1, src2, src3, nbits);
386389

387390
return !(((*src1 | *src2) ^ *src3) & BITMAP_LAST_WORD_MASK(nbits));
388391
}
389392

390-
static inline bool bitmap_intersects(const unsigned long *src1,
391-
const unsigned long *src2,
392-
unsigned int nbits)
393+
static __always_inline
394+
bool bitmap_intersects(const unsigned long *src1, const unsigned long *src2, unsigned int nbits)
393395
{
394396
if (small_const_nbits(nbits))
395397
return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
396398
else
397399
return __bitmap_intersects(src1, src2, nbits);
398400
}
399401

400-
static inline bool bitmap_subset(const unsigned long *src1,
401-
const unsigned long *src2, unsigned int nbits)
402+
static __always_inline
403+
bool bitmap_subset(const unsigned long *src1, const unsigned long *src2, unsigned int nbits)
402404
{
403405
if (small_const_nbits(nbits))
404406
return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits));
405407
else
406408
return __bitmap_subset(src1, src2, nbits);
407409
}
408410

409-
static inline bool bitmap_empty(const unsigned long *src, unsigned nbits)
411+
static __always_inline
412+
bool bitmap_empty(const unsigned long *src, unsigned nbits)
410413
{
411414
if (small_const_nbits(nbits))
412415
return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
413416

414417
return find_first_bit(src, nbits) == nbits;
415418
}
416419

417-
static inline bool bitmap_full(const unsigned long *src, unsigned int nbits)
420+
static __always_inline
421+
bool bitmap_full(const unsigned long *src, unsigned int nbits)
418422
{
419423
if (small_const_nbits(nbits))
420424
return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
@@ -448,8 +452,8 @@ unsigned long bitmap_weight_andnot(const unsigned long *src1,
448452
return __bitmap_weight_andnot(src1, src2, nbits);
449453
}
450454

451-
static __always_inline void bitmap_set(unsigned long *map, unsigned int start,
452-
unsigned int nbits)
455+
static __always_inline
456+
void bitmap_set(unsigned long *map, unsigned int start, unsigned int nbits)
453457
{
454458
if (__builtin_constant_p(nbits) && nbits == 1)
455459
__set_bit(start, map);
@@ -464,8 +468,8 @@ static __always_inline void bitmap_set(unsigned long *map, unsigned int start,
464468
__bitmap_set(map, start, nbits);
465469
}
466470

467-
static __always_inline void bitmap_clear(unsigned long *map, unsigned int start,
468-
unsigned int nbits)
471+
static __always_inline
472+
void bitmap_clear(unsigned long *map, unsigned int start, unsigned int nbits)
469473
{
470474
if (__builtin_constant_p(nbits) && nbits == 1)
471475
__clear_bit(start, map);
@@ -480,29 +484,32 @@ static __always_inline void bitmap_clear(unsigned long *map, unsigned int start,
480484
__bitmap_clear(map, start, nbits);
481485
}
482486

483-
static inline void bitmap_shift_right(unsigned long *dst, const unsigned long *src,
484-
unsigned int shift, unsigned int nbits)
487+
static __always_inline
488+
void bitmap_shift_right(unsigned long *dst, const unsigned long *src,
489+
unsigned int shift, unsigned int nbits)
485490
{
486491
if (small_const_nbits(nbits))
487492
*dst = (*src & BITMAP_LAST_WORD_MASK(nbits)) >> shift;
488493
else
489494
__bitmap_shift_right(dst, src, shift, nbits);
490495
}
491496

492-
static inline void bitmap_shift_left(unsigned long *dst, const unsigned long *src,
493-
unsigned int shift, unsigned int nbits)
497+
static __always_inline
498+
void bitmap_shift_left(unsigned long *dst, const unsigned long *src,
499+
unsigned int shift, unsigned int nbits)
494500
{
495501
if (small_const_nbits(nbits))
496502
*dst = (*src << shift) & BITMAP_LAST_WORD_MASK(nbits);
497503
else
498504
__bitmap_shift_left(dst, src, shift, nbits);
499505
}
500506

501-
static inline void bitmap_replace(unsigned long *dst,
502-
const unsigned long *old,
503-
const unsigned long *new,
504-
const unsigned long *mask,
505-
unsigned int nbits)
507+
static __always_inline
508+
void bitmap_replace(unsigned long *dst,
509+
const unsigned long *old,
510+
const unsigned long *new,
511+
const unsigned long *mask,
512+
unsigned int nbits)
506513
{
507514
if (small_const_nbits(nbits))
508515
*dst = (*old & ~(*mask)) | (*new & *mask);
@@ -545,8 +552,9 @@ static inline void bitmap_replace(unsigned long *dst,
545552
* bitmap_gather() can be seen as the 'reverse' bitmap_scatter() operation.
546553
* See bitmap_scatter() for details related to this relationship.
547554
*/
548-
static inline void bitmap_scatter(unsigned long *dst, const unsigned long *src,
549-
const unsigned long *mask, unsigned int nbits)
555+
static __always_inline
556+
void bitmap_scatter(unsigned long *dst, const unsigned long *src,
557+
const unsigned long *mask, unsigned int nbits)
550558
{
551559
unsigned int n = 0;
552560
unsigned int bit;
@@ -599,8 +607,9 @@ static inline void bitmap_scatter(unsigned long *dst, const unsigned long *src,
599607
* bitmap_scatter(res, src, mask, n) and a call to
600608
* bitmap_scatter(res, result, mask, n) will lead to the same res value.
601609
*/
602-
static inline void bitmap_gather(unsigned long *dst, const unsigned long *src,
603-
const unsigned long *mask, unsigned int nbits)
610+
static __always_inline
611+
void bitmap_gather(unsigned long *dst, const unsigned long *src,
612+
const unsigned long *mask, unsigned int nbits)
604613
{
605614
unsigned int n = 0;
606615
unsigned int bit;
@@ -611,9 +620,9 @@ static inline void bitmap_gather(unsigned long *dst, const unsigned long *src,
611620
__assign_bit(n++, dst, test_bit(bit, src));
612621
}
613622

614-
static inline void bitmap_next_set_region(unsigned long *bitmap,
615-
unsigned int *rs, unsigned int *re,
616-
unsigned int end)
623+
static __always_inline
624+
void bitmap_next_set_region(unsigned long *bitmap, unsigned int *rs,
625+
unsigned int *re, unsigned int end)
617626
{
618627
*rs = find_next_bit(bitmap, end, *rs);
619628
*re = find_next_zero_bit(bitmap, end, *rs + 1);
@@ -628,7 +637,8 @@ static inline void bitmap_next_set_region(unsigned long *bitmap,
628637
* This is the complement to __bitmap_find_free_region() and releases
629638
* the found region (by clearing it in the bitmap).
630639
*/
631-
static inline void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order)
640+
static __always_inline
641+
void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order)
632642
{
633643
bitmap_clear(bitmap, pos, BIT(order));
634644
}
@@ -644,7 +654,8 @@ static inline void bitmap_release_region(unsigned long *bitmap, unsigned int pos
644654
* Returns: 0 on success, or %-EBUSY if specified region wasn't
645655
* free (not all bits were zero).
646656
*/
647-
static inline int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order)
657+
static __always_inline
658+
int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order)
648659
{
649660
unsigned int len = BIT(order);
650661

@@ -668,7 +679,8 @@ static inline int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos
668679
* Returns: the bit offset in bitmap of the allocated region,
669680
* or -errno on failure.
670681
*/
671-
static inline int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order)
682+
static __always_inline
683+
int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order)
672684
{
673685
unsigned int pos, end; /* scans bitmap by regions of size order */
674686

@@ -722,7 +734,7 @@ static inline int bitmap_find_free_region(unsigned long *bitmap, unsigned int bi
722734
* That is ``(u32 *)(&val)[0]`` gets the upper 32 bits,
723735
* but we expect the lower 32-bits of u64.
724736
*/
725-
static inline void bitmap_from_u64(unsigned long *dst, u64 mask)
737+
static __always_inline void bitmap_from_u64(unsigned long *dst, u64 mask)
726738
{
727739
bitmap_from_arr64(dst, &mask, 64);
728740
}
@@ -737,9 +749,8 @@ static inline void bitmap_from_u64(unsigned long *dst, u64 mask)
737749
* @map memory region. For @nbits = 0 and @nbits > BITS_PER_LONG the return
738750
* value is undefined.
739751
*/
740-
static inline unsigned long bitmap_read(const unsigned long *map,
741-
unsigned long start,
742-
unsigned long nbits)
752+
static __always_inline
753+
unsigned long bitmap_read(const unsigned long *map, unsigned long start, unsigned long nbits)
743754
{
744755
size_t index = BIT_WORD(start);
745756
unsigned long offset = start % BITS_PER_LONG;
@@ -772,8 +783,9 @@ static inline unsigned long bitmap_read(const unsigned long *map,
772783
*
773784
* For @nbits == 0 and @nbits > BITS_PER_LONG no writes are performed.
774785
*/
775-
static inline void bitmap_write(unsigned long *map, unsigned long value,
776-
unsigned long start, unsigned long nbits)
786+
static __always_inline
787+
void bitmap_write(unsigned long *map, unsigned long value,
788+
unsigned long start, unsigned long nbits)
777789
{
778790
size_t index;
779791
unsigned long offset;

0 commit comments

Comments
 (0)