Now that bitmap_*_region() functions are implemented as thin wrappers around others, it's worth to move them to the header, as it opens room for compile-time optimizations.
Showing the changes to include/linux/bitmap.h (1 of 2 files). Show all
Unified · Split
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | #include <linux/align.h> | 7 | #include <linux/align.h> |
| 8 | #include <linux/bitops.h> | 8 | #include <linux/bitops.h> |
| 9 | #include <linux/errno.h> | ||
| 9 | #include <linux/find.h> | 10 | #include <linux/find.h> |
| 10 | #include <linux/limits.h> | 11 | #include <linux/limits.h> |
| 11 | #include <linux/string.h> | 12 | #include <linux/string.h> |
| @@ -209,9 +210,6 @@ void bitmap_onto(unsigned long *dst, const unsigned long *orig, · 197 unmodified lines | |||
| 209 | const unsigned long *relmap, unsigned int bits); | 210 | const unsigned long *relmap, unsigned int bits); |
| 210 | void bitmap_fold(unsigned long *dst, const unsigned long *orig, | 211 | void bitmap_fold(unsigned long *dst, const unsigned long *orig, |
| 211 | unsigned int sz, unsigned int nbits); | 212 | unsigned int sz, unsigned int nbits); |
| 212 | int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order); | ||
| 213 | void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order); | ||
| 214 | int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order); | ||
| 215 | 213 | ||
| 216 | #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) | 214 | #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) |
| 217 | #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) | 215 | #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) |
| @@ -497,6 +495,66 @@ static inline void bitmap_next_set_region(unsigned long *bitmap, · 279 unmodified lines | |||
| 497 | *re = find_next_zero_bit(bitmap, end, *rs + 1); | 495 | *re = find_next_zero_bit(bitmap, end, *rs + 1); |
| 498 | } | 496 | } |
| 499 | 497 | ||
| 498 | /** | ||
| 499 | * bitmap_release_region - release allocated bitmap region | ||
| 500 | * @bitmap: array of unsigned longs corresponding to the bitmap | ||
| 501 | * @pos: beginning of bit region to release | ||
| 502 | * @order: region size (log base 2 of number of bits) to release | ||
| 503 | * | ||
| 504 | * This is the complement to __bitmap_find_free_region() and releases | ||
| 505 | * the found region (by clearing it in the bitmap). | ||
| 506 | */ | ||
| 507 | static inline void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order) | ||
| 508 | { | ||
| 509 | bitmap_clear(bitmap, pos, BIT(order)); | ||
| 510 | } | ||
| 511 | |||
| 512 | /** | ||
| 513 | * bitmap_allocate_region - allocate bitmap region | ||
| 514 | * @bitmap: array of unsigned longs corresponding to the bitmap | ||
| 515 | * @pos: beginning of bit region to allocate | ||
| 516 | * @order: region size (log base 2 of number of bits) to allocate | ||
| 517 | * | ||
| 518 | * Allocate (set bits in) a specified region of a bitmap. | ||
| 519 | * | ||
| 520 | * Returns: 0 on success, or %-EBUSY if specified region wasn't | ||
| 521 | * free (not all bits were zero). | ||
| 522 | */ | ||
| 523 | static inline int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order) | ||
| 524 | { | ||
| 525 | unsigned int len = BIT(order); | ||
| 526 | |||
| 527 | if (find_next_bit(bitmap, pos + len, pos) < pos + len) | ||
| 528 | return -EBUSY; | ||
| 529 | bitmap_set(bitmap, pos, len); | ||
| 530 | return 0; | ||
| 531 | } | ||
| 532 | |||
| 533 | /** | ||
| 534 | * bitmap_find_free_region - find a contiguous aligned mem region | ||
| 535 | * @bitmap: array of unsigned longs corresponding to the bitmap | ||
| 536 | * @bits: number of bits in the bitmap | ||
| 537 | * @order: region size (log base 2 of number of bits) to find | ||
| 538 | * | ||
| 539 | * Find a region of free (zero) bits in a @bitmap of @bits bits and | ||
| 540 | * allocate them (set them to one). Only consider regions of length | ||
| 541 | * a power (@order) of two, aligned to that power of two, which | ||
| 542 | * makes the search algorithm much faster. | ||
| 543 | * | ||
| 544 | * Returns: the bit offset in bitmap of the allocated region, | ||
| 545 | * or -errno on failure. | ||
| 546 | */ | ||
| 547 | static inline int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order) | ||
| 548 | { | ||
| 549 | unsigned int pos, end; /* scans bitmap by regions of size order */ | ||
| 550 | |||
| 551 | for (pos = 0; (end = pos + BIT(order)) <= bits; pos = end) { | ||
| 552 | if (!bitmap_allocate_region(bitmap, pos, order)) | ||
| 553 | return pos; | ||
| 554 | } | ||
| 555 | return -ENOMEM; | ||
| 556 | } | ||
| 557 | |||
| 500 | /** | 558 | /** |
| 501 | * BITMAP_FROM_U64() - Represent u64 value in the format suitable for bitmap. | 559 | * BITMAP_FROM_U64() - Represent u64 value in the format suitable for bitmap. |
| 502 | * @n: u64 value | 560 | * @n: u64 value |