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 | 7 | #include <linux/align.h> |
| 8 | 8 | #include <linux/bitops.h> |
| 9 | +#include <linux/errno.h> | |
| 9 | 10 | #include <linux/find.h> |
| 10 | 11 | #include <linux/limits.h> |
| 11 | 12 | #include <linux/string.h> |
| @@ -209,9 +210,6 @@ void bitmap_onto(unsigned long *dst, const unsigned long *orig, · 197 unmodified lines | ||
| 209 | 210 | const unsigned long *relmap, unsigned int bits); |
| 210 | 211 | void bitmap_fold(unsigned long *dst, const unsigned long *orig, |
| 211 | 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 | 214 | #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) |
| 217 | 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 | 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 | 559 | * BITMAP_FROM_U64() - Represent u64 value in the format suitable for bitmap. |
| 502 | 560 | * @n: u64 value |