aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2006-06-23 05:03:46 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-23 10:42:52 -0400
commite0a42726794f71336ff4b26084d453dd597471ce (patch)
tree31debb23f7cce0510a63755f0c4297086761f623
parent668e0d8f1a02fd75f1c1e8142a6b08455914242c (diff)
[PATCH] mm/slab.c: fix early init assumption
The SLAB bootstrap code assumes that the first two kmalloc caches created (the INDEX_AC and INDEX_L3 kmalloc caches) wont be off-slab. But due to AC and L3 structure size increase in lockdep, one of them ended up being off-slab, and subsequently crashing with: Unable to handle kernel NULL pointer dereference at 0000000000000000 RIP: [<ffffffff80267478>] kmem_cache_alloc+0x26/0x7d The fix is to introduce a bootstrap flag and to use it to prevent off-slab caches being created so early during bootup. (The calculation for off-slab caches is quite complex so i didnt want to complicate things with introducing yet another INDEX_ calculation, the flag approach is simpler and smaller.) Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: Manfred Spraul <manfred@colorfullife.com> Cc: Pekka Enberg <penberg@cs.helsinki.fi> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--mm/slab.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/mm/slab.c b/mm/slab.c
index e3260db04b9e..664c3a10acf2 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -331,6 +331,8 @@ static __always_inline int index_of(const size_t size)
331 return 0; 331 return 0;
332} 332}
333 333
334static int slab_early_init = 1;
335
334#define INDEX_AC index_of(sizeof(struct arraycache_init)) 336#define INDEX_AC index_of(sizeof(struct arraycache_init))
335#define INDEX_L3 index_of(sizeof(struct kmem_list3)) 337#define INDEX_L3 index_of(sizeof(struct kmem_list3))
336 338
@@ -1376,6 +1378,8 @@ void __init kmem_cache_init(void)
1376 NULL, NULL); 1378 NULL, NULL);
1377 } 1379 }
1378 1380
1381 slab_early_init = 0;
1382
1379 while (sizes->cs_size != ULONG_MAX) { 1383 while (sizes->cs_size != ULONG_MAX) {
1380 /* 1384 /*
1381 * For performance, all the general caches are L1 aligned. 1385 * For performance, all the general caches are L1 aligned.
@@ -2106,8 +2110,12 @@ kmem_cache_create (const char *name, size_t size, size_t align,
2106#endif 2110#endif
2107#endif 2111#endif
2108 2112
2109 /* Determine if the slab management is 'on' or 'off' slab. */ 2113 /*
2110 if (size >= (PAGE_SIZE >> 3)) 2114 * Determine if the slab management is 'on' or 'off' slab.
2115 * (bootstrapping cannot cope with offslab caches so don't do
2116 * it too early on.)
2117 */
2118 if ((size >= (PAGE_SIZE >> 3)) && !slab_early_init)
2111 /* 2119 /*
2112 * Size is large, assume best to place the slab management obj 2120 * Size is large, assume best to place the slab management obj
2113 * off-slab (should allow better packing of objs). 2121 * off-slab (should allow better packing of objs).