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.
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 |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/bitops.h> |
| 9 | 9 | #include <linux/ctype.h> |
| 10 | 10 | #include <linux/device.h> |
| 11 | −#include <linux/errno.h> | |
| 12 | 11 | #include <linux/export.h> |
| 13 | 12 | #include <linux/slab.h> |
| 14 | 13 | |
| @@ -708,69 +707,6 @@ void bitmap_fold(unsigned long *dst, const unsigned long *orig, · 693 unmodified lines | ||
| 708 | 707 | } |
| 709 | 708 | #endif /* CONFIG_NUMA */ |
| 710 | 709 | |
| 711 | −/** | |
| 712 | − * bitmap_find_free_region - find a contiguous aligned mem region | |
| 713 | − * @bitmap: array of unsigned longs corresponding to the bitmap | |
| 714 | − * @bits: number of bits in the bitmap | |
| 715 | − * @order: region size (log base 2 of number of bits) to find | |
| 716 | − * | |
| 717 | − * Find a region of free (zero) bits in a @bitmap of @bits bits and | |
| 718 | − * allocate them (set them to one). Only consider regions of length | |
| 719 | − * a power (@order) of two, aligned to that power of two, which | |
| 720 | − * makes the search algorithm much faster. | |
| 721 | − * | |
| 722 | − * Return: the bit offset in bitmap of the allocated region, | |
| 723 | − * or -errno on failure. | |
| 724 | − */ | |
| 725 | −int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order) | |
| 726 | −{ | |
| 727 | − unsigned int pos, end; /* scans bitmap by regions of size order */ | |
| 728 | − | |
| 729 | − for (pos = 0; (end = pos + BIT(order)) <= bits; pos = end) { | |
| 730 | − if (!bitmap_allocate_region(bitmap, pos, order)) | |
| 731 | − return pos; | |
| 732 | − } | |
| 733 | − return -ENOMEM; | |
| 734 | −} | |
| 735 | −EXPORT_SYMBOL(bitmap_find_free_region); | |
| 736 | − | |
| 737 | −/** | |
| 738 | − * bitmap_release_region - release allocated bitmap region | |
| 739 | − * @bitmap: array of unsigned longs corresponding to the bitmap | |
| 740 | − * @pos: beginning of bit region to release | |
| 741 | − * @order: region size (log base 2 of number of bits) to release | |
| 742 | − * | |
| 743 | − * This is the complement to __bitmap_find_free_region() and releases | |
| 744 | − * the found region (by clearing it in the bitmap). | |
| 745 | − */ | |
| 746 | −void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order) | |
| 747 | −{ | |
| 748 | − bitmap_clear(bitmap, pos, BIT(order)); | |
| 749 | −} | |
| 750 | −EXPORT_SYMBOL(bitmap_release_region); | |
| 751 | − | |
| 752 | −/** | |
| 753 | − * bitmap_allocate_region - allocate bitmap region | |
| 754 | − * @bitmap: array of unsigned longs corresponding to the bitmap | |
| 755 | − * @pos: beginning of bit region to allocate | |
| 756 | − * @order: region size (log base 2 of number of bits) to allocate | |
| 757 | − * | |
| 758 | − * Allocate (set bits in) a specified region of a bitmap. | |
| 759 | − * | |
| 760 | − * Return: 0 on success, or %-EBUSY if specified region wasn't | |
| 761 | − * free (not all bits were zero). | |
| 762 | − */ | |
| 763 | −int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order) | |
| 764 | −{ | |
| 765 | − unsigned int len = BIT(order); | |
| 766 | − | |
| 767 | − if (find_next_bit(bitmap, pos + len, pos) < pos + len) | |
| 768 | − return -EBUSY; | |
| 769 | − bitmap_set(bitmap, pos, len); | |
| 770 | − return 0; | |
| 771 | −} | |
| 772 | −EXPORT_SYMBOL(bitmap_allocate_region); | |
| 773 | − | |
| 774 | 710 | unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags) |
| 775 | 711 | { |
| 776 | 712 | return kmalloc_array(BITS_TO_LONGS(nbits), sizeof(unsigned long), |