diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-03-01 02:55:20 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-03-01 02:55:20 -0500 |
| commit | 35858adbfca13678af99fb31618ef4428d6dedb0 (patch) | |
| tree | 3336feaa61324486945816cb52c347733e7c0821 /lib/genalloc.c | |
| parent | 197d4db752e67160d79fed09968c2140376a80a3 (diff) | |
| parent | 4b70858ba8d4537daf782defebe5f2ff80ccef2b (diff) | |
Merge branch 'next' into for-linus
Diffstat (limited to 'lib/genalloc.c')
| -rw-r--r-- | lib/genalloc.c | 33 |
1 files changed, 12 insertions, 21 deletions
diff --git a/lib/genalloc.c b/lib/genalloc.c index eed2bdb865e7..e67f97495dd5 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/bitmap.h> | ||
| 14 | #include <linux/genalloc.h> | 15 | #include <linux/genalloc.h> |
| 15 | 16 | ||
| 16 | 17 | ||
| @@ -114,7 +115,7 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) | |||
| 114 | struct gen_pool_chunk *chunk; | 115 | struct gen_pool_chunk *chunk; |
| 115 | unsigned long addr, flags; | 116 | unsigned long addr, flags; |
| 116 | int order = pool->min_alloc_order; | 117 | int order = pool->min_alloc_order; |
| 117 | int nbits, bit, start_bit, end_bit; | 118 | int nbits, start_bit, end_bit; |
| 118 | 119 | ||
| 119 | if (size == 0) | 120 | if (size == 0) |
| 120 | return 0; | 121 | return 0; |
| @@ -129,29 +130,19 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) | |||
| 129 | end_bit -= nbits + 1; | 130 | end_bit -= nbits + 1; |
| 130 | 131 | ||
| 131 | spin_lock_irqsave(&chunk->lock, flags); | 132 | spin_lock_irqsave(&chunk->lock, flags); |
| 132 | bit = -1; | 133 | start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit, 0, |
| 133 | while (bit + 1 < end_bit) { | 134 | nbits, 0); |
| 134 | bit = find_next_zero_bit(chunk->bits, end_bit, bit + 1); | 135 | if (start_bit >= end_bit) { |
| 135 | if (bit >= end_bit) | ||
| 136 | break; | ||
| 137 | |||
| 138 | start_bit = bit; | ||
| 139 | if (nbits > 1) { | ||
| 140 | bit = find_next_bit(chunk->bits, bit + nbits, | ||
| 141 | bit + 1); | ||
| 142 | if (bit - start_bit < nbits) | ||
| 143 | continue; | ||
| 144 | } | ||
| 145 | |||
| 146 | addr = chunk->start_addr + | ||
| 147 | ((unsigned long)start_bit << order); | ||
| 148 | while (nbits--) | ||
| 149 | __set_bit(start_bit++, chunk->bits); | ||
| 150 | spin_unlock_irqrestore(&chunk->lock, flags); | 136 | spin_unlock_irqrestore(&chunk->lock, flags); |
| 151 | read_unlock(&pool->lock); | 137 | continue; |
| 152 | return addr; | ||
| 153 | } | 138 | } |
| 139 | |||
| 140 | addr = chunk->start_addr + ((unsigned long)start_bit << order); | ||
| 141 | |||
| 142 | bitmap_set(chunk->bits, start_bit, nbits); | ||
| 154 | spin_unlock_irqrestore(&chunk->lock, flags); | 143 | spin_unlock_irqrestore(&chunk->lock, flags); |
| 144 | read_unlock(&pool->lock); | ||
| 145 | return addr; | ||
| 155 | } | 146 | } |
| 156 | read_unlock(&pool->lock); | 147 | read_unlock(&pool->lock); |
| 157 | return 0; | 148 | return 0; |
