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 | #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 |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <linux/bitops.h> | 8 | #include <linux/bitops.h> |
| 9 | #include <linux/ctype.h> | 9 | #include <linux/ctype.h> |
| 10 | #include <linux/device.h> | 10 | #include <linux/device.h> |
| 11 | #include <linux/errno.h> | ||
| 12 | #include <linux/export.h> | 11 | #include <linux/export.h> |
| 13 | #include <linux/slab.h> | 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 | #endif /* CONFIG_NUMA */ | 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 | unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags) | 710 | unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags) |
| 775 | { | 711 | { |
| 776 | return kmalloc_array(BITS_TO_LONGS(nbits), sizeof(unsigned long), | 712 | return kmalloc_array(BITS_TO_LONGS(nbits), sizeof(unsigned long), |