Commit a26e16a5 authored by Nick Piggin's avatar Nick Piggin Committed by Pekka Enberg

SLQB: fix dumb early allocation cache

The dumb early allocation cache had a bug where it could allow allocation
to go past the end of a page, which could cause crashes or random memory
corruption. Fix this and simplify the logic.

[ penberg@cs.helsinki.fi: fix whitespace issues pointed out by Anton Vorontsov]
Reported-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
Tested-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
Signed-off-by: default avatarPekka Enberg <penberg@cs.helsinki.fi>
parent 5c418844
...@@ -2185,8 +2185,11 @@ static void *kmem_cache_dyn_array_alloc(int ids) ...@@ -2185,8 +2185,11 @@ static void *kmem_cache_dyn_array_alloc(int ids)
{ {
size_t size = sizeof(void *) * ids; size_t size = sizeof(void *) * ids;
BUG_ON(!size);
if (unlikely(!slab_is_available())) { if (unlikely(!slab_is_available())) {
static void *nextmem; static void *nextmem;
static size_t nextleft;
void *ret; void *ret;
/* /*
...@@ -2194,16 +2197,16 @@ static void *kmem_cache_dyn_array_alloc(int ids) ...@@ -2194,16 +2197,16 @@ static void *kmem_cache_dyn_array_alloc(int ids)
* never get freed by definition so we can do it rather * never get freed by definition so we can do it rather
* simply. * simply.
*/ */
if (!nextmem) { if (size > nextleft) {
nextmem = alloc_pages_exact(size, GFP_KERNEL); nextmem = alloc_pages_exact(size, GFP_KERNEL);
if (!nextmem) if (!nextmem)
return NULL; return NULL;
nextleft = roundup(size, PAGE_SIZE);
} }
ret = nextmem; ret = nextmem;
nextmem = (void *)((unsigned long)ret + size); nextleft -= size;
if ((unsigned long)ret >> PAGE_SHIFT != nextmem += size;
(unsigned long)nextmem >> PAGE_SHIFT)
nextmem = NULL;
memset(ret, 0, size); memset(ret, 0, size);
return ret; return ret;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment