diff options
Diffstat (limited to 'lib/genalloc.c')
| -rw-r--r-- | lib/genalloc.c | 22 | 
1 files changed, 13 insertions, 9 deletions
| diff --git a/lib/genalloc.c b/lib/genalloc.c index b35cfa9bc3d4..26cf20be72b7 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -37,6 +37,11 @@  #include <linux/of_address.h>  #include <linux/of_device.h> +static inline size_t chunk_size(const struct gen_pool_chunk *chunk) +{ +	return chunk->end_addr - chunk->start_addr + 1; +} +  static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set)  {  	unsigned long val, nval; @@ -182,13 +187,13 @@ 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 = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid); +	chunk = kzalloc_node(nbytes, GFP_KERNEL, nid);  	if (unlikely(chunk == NULL))  		return -ENOMEM;  	chunk->phys_addr = phys;  	chunk->start_addr = virt; -	chunk->end_addr = virt + size; +	chunk->end_addr = virt + size - 1;  	atomic_set(&chunk->avail, size);  	spin_lock(&pool->lock); @@ -213,7 +218,7 @@ phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long addr)  	rcu_read_lock();  	list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { -		if (addr >= chunk->start_addr && addr < chunk->end_addr) { +		if (addr >= chunk->start_addr && addr <= chunk->end_addr) {  			paddr = chunk->phys_addr + (addr - chunk->start_addr);  			break;  		} @@ -242,7 +247,7 @@ void gen_pool_destroy(struct gen_pool *pool)  		chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);  		list_del(&chunk->next_chunk); -		end_bit = (chunk->end_addr - chunk->start_addr) >> order; +		end_bit = chunk_size(chunk) >> order;  		bit = find_next_bit(chunk->bits, end_bit, 0);  		BUG_ON(bit < end_bit); @@ -283,7 +288,7 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)  		if (size > atomic_read(&chunk->avail))  			continue; -		end_bit = (chunk->end_addr - chunk->start_addr) >> order; +		end_bit = chunk_size(chunk) >> order;  retry:  		start_bit = pool->algo(chunk->bits, end_bit, start_bit, nbits,  				pool->data); @@ -330,8 +335,8 @@ void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size)  	nbits = (size + (1UL << order) - 1) >> order;  	rcu_read_lock();  	list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { -		if (addr >= chunk->start_addr && addr < chunk->end_addr) { -			BUG_ON(addr + size > chunk->end_addr); +		if (addr >= chunk->start_addr && addr <= chunk->end_addr) { +			BUG_ON(addr + size - 1 > chunk->end_addr);  			start_bit = (addr - chunk->start_addr) >> order;  			remain = bitmap_clear_ll(chunk->bits, start_bit, nbits);  			BUG_ON(remain); @@ -400,7 +405,7 @@ size_t gen_pool_size(struct gen_pool *pool)  	rcu_read_lock();  	list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) -		size += chunk->end_addr - chunk->start_addr; +		size += chunk_size(chunk);  	rcu_read_unlock();  	return size;  } @@ -519,7 +524,6 @@ struct gen_pool *devm_gen_pool_create(struct device *dev, int min_alloc_order,  /**   * dev_get_gen_pool - Obtain the gen_pool (if any) for a device   * @dev: device to retrieve the gen_pool from - * @name: Optional name for the gen_pool, usually NULL   *   * Returns the gen_pool for the device if one is present, or NULL.   */ | 
