aboutsummaryrefslogtreecommitdiffstats
path: root/mm/slab.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-03-06 20:44:43 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-06 20:44:43 -0500
commit9888e6fa7b68d9c8cc2c162a90979825ab45150a (patch)
tree83e46fb733008fa753269d338f90ad255cc59f53 /mm/slab.c
parentf716d8303345698728d9f8ce76a82a795a5be275 (diff)
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>
Diffstat (limited to 'mm/slab.c')
-rw-r--r--mm/slab.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/mm/slab.c b/mm/slab.c
index 2b0b1519bb74..f2e92dc1c9ce 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1628,36 +1628,36 @@ static inline size_t calculate_slab_order(struct kmem_cache *cachep,
1628 size_t size, size_t align, unsigned long flags) 1628 size_t size, size_t align, unsigned long flags)
1629{ 1629{
1630 size_t left_over = 0; 1630 size_t left_over = 0;
1631 int gfporder;
1631 1632
1632 for (;; cachep->gfporder++) { 1633 for (gfporder = 0 ; gfporder <= MAX_GFP_ORDER; gfporder++) {
1633 unsigned int num; 1634 unsigned int num;
1634 size_t remainder; 1635 size_t remainder;
1635 1636
1636 if (cachep->gfporder > MAX_GFP_ORDER) { 1637 cache_estimate(gfporder, size, align, flags, &remainder, &num);
1637 cachep->num = 0;
1638 break;
1639 }
1640
1641 cache_estimate(cachep->gfporder, size, align, flags,
1642 &remainder, &num);
1643 if (!num) 1638 if (!num)
1644 continue; 1639 continue;
1640
1645 /* More than offslab_limit objects will cause problems */ 1641 /* More than offslab_limit objects will cause problems */
1646 if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit) 1642 if ((flags & CFLGS_OFF_SLAB) && num > offslab_limit)
1647 break; 1643 break;
1648 1644
1645 /* Found something acceptable - save it away */
1649 cachep->num = num; 1646 cachep->num = num;
1647 cachep->gfporder = gfporder;
1650 left_over = remainder; 1648 left_over = remainder;
1651 1649
1652 /* 1650 /*
1653 * Large number of objects is good, but very large slabs are 1651 * Large number of objects is good, but very large slabs are
1654 * currently bad for the gfp()s. 1652 * currently bad for the gfp()s.
1655 */ 1653 */
1656 if (cachep->gfporder >= slab_break_gfp_order) 1654 if (gfporder >= slab_break_gfp_order)
1657 break; 1655 break;
1658 1656
1659 if ((left_over * 8) <= (PAGE_SIZE << cachep->gfporder)) 1657 /*
1660 /* Acceptable internal fragmentation */ 1658 * Acceptable internal fragmentation?
1659 */
1660 if ((left_over * 8) <= (PAGE_SIZE << gfporder))
1661 break; 1661 break;
1662 } 1662 }
1663 return left_over; 1663 return left_over;