diff options
Diffstat (limited to 'lib/genalloc.c')
| -rw-r--r-- | lib/genalloc.c | 25 | 
1 files changed, 15 insertions, 10 deletions
diff --git a/lib/genalloc.c b/lib/genalloc.c index ca06adc4f445..7e85d1e37a6e 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -35,6 +35,7 @@  #include <linux/interrupt.h>  #include <linux/genalloc.h>  #include <linux/of_device.h> +#include <linux/vmalloc.h>  static inline size_t chunk_size(const struct gen_pool_chunk *chunk)  { @@ -187,7 +188,7 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy  	int nbytes = sizeof(struct gen_pool_chunk) +  				BITS_TO_LONGS(nbits) * sizeof(long); -	chunk = kzalloc_node(nbytes, GFP_KERNEL, nid); +	chunk = vzalloc_node(nbytes, nid);  	if (unlikely(chunk == NULL))  		return -ENOMEM; @@ -251,7 +252,7 @@ void gen_pool_destroy(struct gen_pool *pool)  		bit = find_next_bit(chunk->bits, end_bit, 0);  		BUG_ON(bit < end_bit); -		kfree(chunk); +		vfree(chunk);  	}  	kfree_const(pool->name);  	kfree(pool); @@ -311,7 +312,7 @@ unsigned long gen_pool_alloc_algo(struct gen_pool *pool, size_t size,  		end_bit = chunk_size(chunk) >> order;  retry:  		start_bit = algo(chunk->bits, end_bit, start_bit, -				 nbits, data, pool); +				 nbits, data, pool, chunk->start_addr);  		if (start_bit >= end_bit)  			continue;  		remain = bitmap_set_ll(chunk->bits, start_bit, nbits); @@ -525,7 +526,7 @@ EXPORT_SYMBOL(gen_pool_set_algo);   */  unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size,  		unsigned long start, unsigned int nr, void *data, -		struct gen_pool *pool) +		struct gen_pool *pool, unsigned long start_addr)  {  	return bitmap_find_next_zero_area(map, size, start, nr, 0);  } @@ -543,16 +544,19 @@ EXPORT_SYMBOL(gen_pool_first_fit);   */  unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size,  		unsigned long start, unsigned int nr, void *data, -		struct gen_pool *pool) +		struct gen_pool *pool, unsigned long start_addr)  {  	struct genpool_data_align *alignment; -	unsigned long align_mask; +	unsigned long align_mask, align_off;  	int order;  	alignment = data;  	order = pool->min_alloc_order;  	align_mask = ((alignment->align + (1UL << order) - 1) >> order) - 1; -	return bitmap_find_next_zero_area(map, size, start, nr, align_mask); +	align_off = (start_addr & (alignment->align - 1)) >> order; + +	return bitmap_find_next_zero_area_off(map, size, start, nr, +					      align_mask, align_off);  }  EXPORT_SYMBOL(gen_pool_first_fit_align); @@ -567,7 +571,7 @@ EXPORT_SYMBOL(gen_pool_first_fit_align);   */  unsigned long gen_pool_fixed_alloc(unsigned long *map, unsigned long size,  		unsigned long start, unsigned int nr, void *data, -		struct gen_pool *pool) +		struct gen_pool *pool, unsigned long start_addr)  {  	struct genpool_data_fixed *fixed_data;  	int order; @@ -601,7 +605,8 @@ EXPORT_SYMBOL(gen_pool_fixed_alloc);   */  unsigned long gen_pool_first_fit_order_align(unsigned long *map,  		unsigned long size, unsigned long start, -		unsigned int nr, void *data, struct gen_pool *pool) +		unsigned int nr, void *data, struct gen_pool *pool, +		unsigned long start_addr)  {  	unsigned long align_mask = roundup_pow_of_two(nr) - 1; @@ -624,7 +629,7 @@ EXPORT_SYMBOL(gen_pool_first_fit_order_align);   */  unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size,  		unsigned long start, unsigned int nr, void *data, -		struct gen_pool *pool) +		struct gen_pool *pool, unsigned long start_addr)  {  	unsigned long start_bit = size;  	unsigned long len = size + 1;  | 
