mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-21 11:53:01 +00:00
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:
parent
f716d83033
commit
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 size, size_t align, unsigned long flags)
|
||||||
{
|
{
|
||||||
size_t left_over = 0;
|
size_t left_over = 0;
|
||||||
|
int gfporder;
|
||||||
|
|
||||||
for (;; cachep->gfporder++) {
|
for (gfporder = 0 ; gfporder <= MAX_GFP_ORDER; gfporder++) {
|
||||||
unsigned int num;
|
unsigned int num;
|
||||||
size_t remainder;
|
size_t remainder;
|
||||||
|
|
||||||
if (cachep->gfporder > MAX_GFP_ORDER) {
|
cache_estimate(gfporder, size, align, flags, &remainder, &num);
|
||||||
cachep->num = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cache_estimate(cachep->gfporder, size, align, flags,
|
|
||||||
&remainder, &num);
|
|
||||||
if (!num)
|
if (!num)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* More than offslab_limit objects will cause problems */
|
/* 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;
|
break;
|
||||||
|
|
||||||
|
/* Found something acceptable - save it away */
|
||||||
cachep->num = num;
|
cachep->num = num;
|
||||||
|
cachep->gfporder = gfporder;
|
||||||
left_over = remainder;
|
left_over = remainder;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Large number of objects is good, but very large slabs are
|
* Large number of objects is good, but very large slabs are
|
||||||
* currently bad for the gfp()s.
|
* currently bad for the gfp()s.
|
||||||
*/
|
*/
|
||||||
if (cachep->gfporder >= slab_break_gfp_order)
|
if (gfporder >= slab_break_gfp_order)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((left_over * 8) <= (PAGE_SIZE << cachep->gfporder))
|
/*
|
||||||
/* Acceptable internal fragmentation */
|
* Acceptable internal fragmentation?
|
||||||
|
*/
|
||||||
|
if ((left_over * 8) <= (PAGE_SIZE << gfporder))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return left_over;
|
return left_over;
|
||||||
|
|
Loading…
Reference in a new issue