Messages in this thread Patch in this message | | | Date | Mon, 29 Apr 2013 17:48:43 +0000 | From | Christoph Lameter <> | Subject | Re: [linux-next-20130422] Bug in SLAB? |
| |
On Tue, 30 Apr 2013, Tetsuo Handa wrote:
> Glauber Costa wrote: > > If I am right, the following (untested) patch should solve the problem. > > This patch did not help; > > kmalloc(8 * 1024 * 1024, GFP_KERNEL) > > still causes both > > include/linux/slab_def.h:136: warning: array subscript is above array bounds > > and > > BUG: unable to handle kernel NULL pointer dereference at 00000058 > IP: [<c10b9d76>] kmem_cache_alloc+0x26/0xb0 > > . > > Christoph Lameter wrote: > > What is MAX_ORDER on the architecture? > > In my environment (x86_32), the constants are > > MAX_ORDER=11 PAGE_SHIFT=12 KMALLOC_SHIFT_HIGH=22 KMALLOC_MAX_SIZE=4194304 >
Ok so the maximum allocation is 11+12=23 which is 8M. KMALLOC_MAX_SIZE amd KMALLOC_SHIFT_HIGH are wrong.
Take the -1 off the constants under #ifdef CONFIG_SLAB in
include/linux/slab.h Index: linux/include/linux/slab.h =================================================================== --- linux.orig/include/linux/slab.h 2013-04-29 12:44:42.339011800 -0500 +++ linux/include/linux/slab.h 2013-04-29 12:48:11.446435859 -0500 @@ -176,8 +176,8 @@ struct kmem_cache { * to do various tricks to work around compiler limitations in order to * ensure proper constant folding. */ -#define KMALLOC_SHIFT_HIGH ((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \ - (MAX_ORDER + PAGE_SHIFT - 1) : 25) +#define KMALLOC_SHIFT_HIGH ((MAX_ORDER + PAGE_SHIFT) <= 26 ? \ + (MAX_ORDER + PAGE_SHIFT) : 26) #define KMALLOC_SHIFT_MAX KMALLOC_SHIFT_HIGH #define KMALLOC_SHIFT_LOW 5 #else @@ -206,9 +206,9 @@ struct kmem_cache { #define KMALLOC_MIN_SIZE (1 << KMALLOC_SHIFT_LOW) #endif
-extern struct kmem_cache *kmalloc_caches[KMALLOC_SHIFT_HIGH + 1]; +extern struct kmem_cache *kmalloc_caches[KMALLOC_SHIFT_HIGH]; #ifdef CONFIG_ZONE_DMA -extern struct kmem_cache *kmalloc_dma_caches[KMALLOC_SHIFT_HIGH + 1]; +extern struct kmem_cache *kmalloc_dma_caches[KMALLOC_SHIFT_HIGH]; #endif
/*
| |