summaryrefslogtreecommitdiff
path: root/mm/slqb.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/slqb.c')
-rw-r--r--mm/slqb.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/mm/slqb.c b/mm/slqb.c
index a6518433bdda..2252070fac66 100644
--- a/mm/slqb.c
+++ b/mm/slqb.c
@@ -2185,8 +2185,11 @@ static void *kmem_cache_dyn_array_alloc(int ids)
{
size_t size = sizeof(void *) * ids;
+ BUG_ON(!size);
+
if (unlikely(!slab_is_available())) {
static void *nextmem;
+ static size_t nextleft;
void *ret;
/*
@@ -2194,16 +2197,16 @@ static void *kmem_cache_dyn_array_alloc(int ids)
* never get freed by definition so we can do it rather
* simply.
*/
- if (!nextmem) {
- nextmem = alloc_pages_exact(size, GFP_KERNEL);
- if (!nextmem)
- return NULL;
+ if (size > nextleft) {
+ nextmem = alloc_pages_exact(size, GFP_KERNEL);
+ if (!nextmem)
+ return NULL;
+ nextleft = roundup(size, PAGE_SIZE);
}
+
ret = nextmem;
- nextmem = (void *)((unsigned long)ret + size);
- if ((unsigned long)ret >> PAGE_SHIFT !=
- (unsigned long)nextmem >> PAGE_SHIFT)
- nextmem = NULL;
+ nextleft -= size;
+ nextmem += size;
memset(ret, 0, size);
return ret;
} else {