aboutsummaryrefslogtreecommitdiffstats
path: root/lib/genalloc.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /lib/genalloc.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'lib/genalloc.c')
-rw-r--r--lib/genalloc.c34
1 files changed, 13 insertions, 21 deletions
diff --git a/lib/genalloc.c b/lib/genalloc.c
index eed2bdb865e7..736c3b06398e 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -10,7 +10,9 @@
10 * Version 2. See the file COPYING for more details. 10 * Version 2. See the file COPYING for more details.
11 */ 11 */
12 12
13#include <linux/slab.h>
13#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/bitmap.h>
14#include <linux/genalloc.h> 16#include <linux/genalloc.h>
15 17
16 18
@@ -114,7 +116,7 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
114 struct gen_pool_chunk *chunk; 116 struct gen_pool_chunk *chunk;
115 unsigned long addr, flags; 117 unsigned long addr, flags;
116 int order = pool->min_alloc_order; 118 int order = pool->min_alloc_order;
117 int nbits, bit, start_bit, end_bit; 119 int nbits, start_bit, end_bit;
118 120
119 if (size == 0) 121 if (size == 0)
120 return 0; 122 return 0;
@@ -129,29 +131,19 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
129 end_bit -= nbits + 1; 131 end_bit -= nbits + 1;
130 132
131 spin_lock_irqsave(&chunk->lock, flags); 133 spin_lock_irqsave(&chunk->lock, flags);
132 bit = -1; 134 start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit, 0,
133 while (bit + 1 < end_bit) { 135 nbits, 0);
134 bit = find_next_zero_bit(chunk->bits, end_bit, bit + 1); 136 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); 137 spin_unlock_irqrestore(&chunk->lock, flags);
151 read_unlock(&pool->lock); 138 continue;
152 return addr;
153 } 139 }
140
141 addr = chunk->start_addr + ((unsigned long)start_bit << order);
142
143 bitmap_set(chunk->bits, start_bit, nbits);
154 spin_unlock_irqrestore(&chunk->lock, flags); 144 spin_unlock_irqrestore(&chunk->lock, flags);
145 read_unlock(&pool->lock);
146 return addr;
155 } 147 }
156 read_unlock(&pool->lock); 148 read_unlock(&pool->lock);
157 return 0; 149 return 0;