diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /lib/genalloc.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'lib/genalloc.c')
-rw-r--r-- | lib/genalloc.c | 34 |
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; |