summaryrefslogtreecommitdiff
path: root/lib/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bitmap.c')
-rw-r--r--lib/bitmap.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 06f7e4fe8d2d..ea190b7047c3 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -1114,14 +1114,23 @@ done:
*/
int bitmap_find_free_region(unsigned long *bitmap, int bits, int order)
{
- int pos, end; /* scans bitmap by regions of size order */
+ int nlongs = BITS_TO_LONGS(bits);
+ int i;
- for (pos = 0 ; (end = pos + (1 << order)) <= bits; pos = end) {
- if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE))
- continue;
- __reg_op(bitmap, pos, order, REG_OP_ALLOC);
- return pos;
- }
+ for (i = 0; i < nlongs; i++)
+ if (bitmap[i] != ~0UL) {
+ int pos = i * BITS_PER_LONG;
+ int nbit = min(bits, pos + BITS_PER_LONG);
+ int end;
+
+ for (; (end = pos + (1 << order)) <= nbit; pos = end) {
+ if (!__reg_op(bitmap, pos, order,
+ REG_OP_ISFREE))
+ continue;
+ __reg_op(bitmap, pos, order, REG_OP_ALLOC);
+ return pos;
+ }
+ }
return -ENOMEM;
}
EXPORT_SYMBOL(bitmap_find_free_region);