lib: genalloc: Change chunk allocation to vmalloc

Change the chunk allocation from kmalloc to vmalloc for
allocations greater than a page. This allows large
chunks to be allocated from physically non-contiguous
memory and increases the chance of the allocation
succeeding.

CRs-fixed: 387655
Signed-off-by: Shubhraprakash Das <sadas@codeaurora.org>
(cherry picked from commit e461457b134e55c3ca68b91b70b8796e3f3dba69)

Change-Id: I576fed3dd33fdfa9742f0c91bea72417c4f0086f
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
This commit is contained in:
Shubhraprakash Das
2012-08-14 00:25:43 -07:00
committed by Stephen Boyd
parent fc8946f5db
commit 93a061a38b

View File

@@ -34,6 +34,7 @@
#include <linux/rculist.h>
#include <linux/interrupt.h>
#include <linux/genalloc.h>
#include <linux/vmalloc.h>
static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set)
{
@@ -178,9 +179,14 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy
int nbytes = sizeof(struct gen_pool_chunk) +
(nbits + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid);
if (nbytes <= PAGE_SIZE)
chunk = kmalloc_node(nbytes, __GFP_ZERO, nid);
else
chunk = vmalloc(nbytes);
if (unlikely(chunk == NULL))
return -ENOMEM;
if (nbytes > PAGE_SIZE)
memset(chunk, 0, nbytes);
chunk->phys_addr = phys;
chunk->start_addr = virt;
@@ -235,14 +241,20 @@ void gen_pool_destroy(struct gen_pool *pool)
int bit, end_bit;
list_for_each_safe(_chunk, _next_chunk, &pool->chunks) {
int nbytes;
chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
list_del(&chunk->next_chunk);
end_bit = (chunk->end_addr - chunk->start_addr) >> order;
nbytes = sizeof(struct gen_pool_chunk) +
(end_bit + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
bit = find_next_bit(chunk->bits, end_bit, 0);
BUG_ON(bit < end_bit);
kfree(chunk);
if (nbytes <= PAGE_SIZE)
kfree(chunk);
else
vfree(chunk);
}
kfree(pool);
return;