summaryrefslogtreecommitdiffstats
path: root/lib/genalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/genalloc.c')
-rw-r--r--lib/genalloc.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/lib/genalloc.c b/lib/genalloc.c
index ca06adc4f445..f365d71cdc77 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -187,7 +187,7 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy
187 int nbytes = sizeof(struct gen_pool_chunk) + 187 int nbytes = sizeof(struct gen_pool_chunk) +
188 BITS_TO_LONGS(nbits) * sizeof(long); 188 BITS_TO_LONGS(nbits) * sizeof(long);
189 189
190 chunk = kzalloc_node(nbytes, GFP_KERNEL, nid); 190 chunk = vzalloc_node(nbytes, nid);
191 if (unlikely(chunk == NULL)) 191 if (unlikely(chunk == NULL))
192 return -ENOMEM; 192 return -ENOMEM;
193 193
@@ -251,7 +251,7 @@ void gen_pool_destroy(struct gen_pool *pool)
251 bit = find_next_bit(chunk->bits, end_bit, 0); 251 bit = find_next_bit(chunk->bits, end_bit, 0);
252 BUG_ON(bit < end_bit); 252 BUG_ON(bit < end_bit);
253 253
254 kfree(chunk); 254 vfree(chunk);
255 } 255 }
256 kfree_const(pool->name); 256 kfree_const(pool->name);
257 kfree(pool); 257 kfree(pool);
@@ -311,7 +311,7 @@ unsigned long gen_pool_alloc_algo(struct gen_pool *pool, size_t size,
311 end_bit = chunk_size(chunk) >> order; 311 end_bit = chunk_size(chunk) >> order;
312retry: 312retry:
313 start_bit = algo(chunk->bits, end_bit, start_bit, 313 start_bit = algo(chunk->bits, end_bit, start_bit,
314 nbits, data, pool); 314 nbits, data, pool, chunk->start_addr);
315 if (start_bit >= end_bit) 315 if (start_bit >= end_bit)
316 continue; 316 continue;
317 remain = bitmap_set_ll(chunk->bits, start_bit, nbits); 317 remain = bitmap_set_ll(chunk->bits, start_bit, nbits);
@@ -525,7 +525,7 @@ EXPORT_SYMBOL(gen_pool_set_algo);
525 */ 525 */
526unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, 526unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size,
527 unsigned long start, unsigned int nr, void *data, 527 unsigned long start, unsigned int nr, void *data,
528 struct gen_pool *pool) 528 struct gen_pool *pool, unsigned long start_addr)
529{ 529{
530 return bitmap_find_next_zero_area(map, size, start, nr, 0); 530 return bitmap_find_next_zero_area(map, size, start, nr, 0);
531} 531}
@@ -543,16 +543,19 @@ EXPORT_SYMBOL(gen_pool_first_fit);
543 */ 543 */
544unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size, 544unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size,
545 unsigned long start, unsigned int nr, void *data, 545 unsigned long start, unsigned int nr, void *data,
546 struct gen_pool *pool) 546 struct gen_pool *pool, unsigned long start_addr)
547{ 547{
548 struct genpool_data_align *alignment; 548 struct genpool_data_align *alignment;
549 unsigned long align_mask; 549 unsigned long align_mask, align_off;
550 int order; 550 int order;
551 551
552 alignment = data; 552 alignment = data;
553 order = pool->min_alloc_order; 553 order = pool->min_alloc_order;
554 align_mask = ((alignment->align + (1UL << order) - 1) >> order) - 1; 554 align_mask = ((alignment->align + (1UL << order) - 1) >> order) - 1;
555 return bitmap_find_next_zero_area(map, size, start, nr, align_mask); 555 align_off = (start_addr & (alignment->align - 1)) >> order;
556
557 return bitmap_find_next_zero_area_off(map, size, start, nr,
558 align_mask, align_off);
556} 559}
557EXPORT_SYMBOL(gen_pool_first_fit_align); 560EXPORT_SYMBOL(gen_pool_first_fit_align);
558 561
@@ -567,7 +570,7 @@ EXPORT_SYMBOL(gen_pool_first_fit_align);
567 */ 570 */
568unsigned long gen_pool_fixed_alloc(unsigned long *map, unsigned long size, 571unsigned long gen_pool_fixed_alloc(unsigned long *map, unsigned long size,
569 unsigned long start, unsigned int nr, void *data, 572 unsigned long start, unsigned int nr, void *data,
570 struct gen_pool *pool) 573 struct gen_pool *pool, unsigned long start_addr)
571{ 574{
572 struct genpool_data_fixed *fixed_data; 575 struct genpool_data_fixed *fixed_data;
573 int order; 576 int order;
@@ -601,7 +604,8 @@ EXPORT_SYMBOL(gen_pool_fixed_alloc);
601 */ 604 */
602unsigned long gen_pool_first_fit_order_align(unsigned long *map, 605unsigned long gen_pool_first_fit_order_align(unsigned long *map,
603 unsigned long size, unsigned long start, 606 unsigned long size, unsigned long start,
604 unsigned int nr, void *data, struct gen_pool *pool) 607 unsigned int nr, void *data, struct gen_pool *pool,
608 unsigned long start_addr)
605{ 609{
606 unsigned long align_mask = roundup_pow_of_two(nr) - 1; 610 unsigned long align_mask = roundup_pow_of_two(nr) - 1;
607 611
@@ -624,7 +628,7 @@ EXPORT_SYMBOL(gen_pool_first_fit_order_align);
624 */ 628 */
625unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, 629unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size,
626 unsigned long start, unsigned int nr, void *data, 630 unsigned long start, unsigned int nr, void *data,
627 struct gen_pool *pool) 631 struct gen_pool *pool, unsigned long start_addr)
628{ 632{
629 unsigned long start_bit = size; 633 unsigned long start_bit = size;
630 unsigned long len = size + 1; 634 unsigned long len = size + 1;