[PATCH] slab: allocate larger cache_cache if order 0 fails

kmem_cache_init() incorrectly assumes that the cache_cache object will fit
in an order 0 allocation. On very large systems, this is not true. Change
the code to try larger order allocations if order 0 fails.

Signed-off-by: Jack Steiner <steiner@sgi.com>
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>

authored by Jack Steiner and committed by Linus Torvalds 07ed76b2 731805b4

+8 -3
+8 -3
mm/slab.c
··· 1124 1124 struct cache_sizes *sizes; 1125 1125 struct cache_names *names; 1126 1126 int i; 1127 + int order; 1127 1128 1128 1129 for (i = 0; i < NUM_INIT_LISTS; i++) { 1129 1130 kmem_list3_init(&initkmem_list3[i]); ··· 1168 1167 1169 1168 cache_cache.buffer_size = ALIGN(cache_cache.buffer_size, cache_line_size()); 1170 1169 1171 - cache_estimate(0, cache_cache.buffer_size, cache_line_size(), 0, 1172 - &left_over, &cache_cache.num); 1170 + for (order = 0; order < MAX_ORDER; order++) { 1171 + cache_estimate(order, cache_cache.buffer_size, 1172 + cache_line_size(), 0, &left_over, &cache_cache.num); 1173 + if (cache_cache.num) 1174 + break; 1175 + } 1173 1176 if (!cache_cache.num) 1174 1177 BUG(); 1175 - 1178 + cache_cache.gfporder = order; 1176 1179 cache_cache.colour = left_over / cache_cache.colour_off; 1177 1180 cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) + 1178 1181 sizeof(struct slab), cache_line_size());