slab: clarify and fix calculate_slab_order()
If we triggered the 'offslab_limit' test, we would return with cachep->gfporder incremented once too many times. This clarifies the logic somewhat, and fixes that bug. Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Родитель
f716d83033
Коммит
9888e6fa7b
24
mm/slab.c
24
mm/slab.c
|
@ -1628,36 +1628,36 @@ static inline size_t calculate_slab_order(struct kmem_cache *cachep,
|
|||
size_t size, size_t align, unsigned long flags)
|
||||
{
|
||||
size_t left_over = 0;
|
||||
int gfporder;
|
||||
|
||||
for (;; cachep->gfporder++) {
|
||||
for (gfporder = 0 ; gfporder <= MAX_GFP_ORDER; gfporder++) {
|
||||
unsigned int num;
|
||||
size_t remainder;
|
||||
|
||||
if (cachep->gfporder > MAX_GFP_ORDER) {
|
||||
cachep->num = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
cache_estimate(cachep->gfporder, size, align, flags,
|
||||
&remainder, &num);
|
||||
cache_estimate(gfporder, size, align, flags, &remainder, &num);
|
||||
if (!num)
|
||||
continue;
|
||||
|
||||
/* More than offslab_limit objects will cause problems */
|
||||
if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit)
|
||||
if ((flags & CFLGS_OFF_SLAB) && num > offslab_limit)
|
||||
break;
|
||||
|
||||
/* Found something acceptable - save it away */
|
||||
cachep->num = num;
|
||||
cachep->gfporder = gfporder;
|
||||
left_over = remainder;
|
||||
|
||||
/*
|
||||
* Large number of objects is good, but very large slabs are
|
||||
* currently bad for the gfp()s.
|
||||
*/
|
||||
if (cachep->gfporder >= slab_break_gfp_order)
|
||||
if (gfporder >= slab_break_gfp_order)
|
||||
break;
|
||||
|
||||
if ((left_over * 8) <= (PAGE_SIZE << cachep->gfporder))
|
||||
/* Acceptable internal fragmentation */
|
||||
/*
|
||||
* Acceptable internal fragmentation?
|
||||
*/
|
||||
if ((left_over * 8) <= (PAGE_SIZE << gfporder))
|
||||
break;
|
||||
}
|
||||
return left_over;
|
||||
|
|
Загрузка…
Ссылка в новой задаче