|
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,
|
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,
|
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
|
|
0 commit comments