aboutsummaryrefslogtreecommitdiffstats
path: root/mm/slub.c
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2007-05-09 05:32:46 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-09 15:30:46 -0400
commit5e6d444ea1f72b8148354a9baf0ea8fa3dd0425b (patch)
treec9c07fd97acd925bfb9c4964240799414243d399 /mm/slub.c
parent45edfa580b8e638c44ec26872bfe75b307ba12d1 (diff)
SLUB: rework slab order determination
In some cases SLUB is creating uselessly slabs that are larger than slub_max_order. Also the layout of some of the slabs was not satisfactory. Go to an iterarive approach. Signed-off-by: Christoph Lameter <clameter@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/slub.c')
-rw-r--r--mm/slub.c66
1 files changed, 52 insertions, 14 deletions
diff --git a/mm/slub.c b/mm/slub.c
index ae2831027802..c81f52a72153 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1577,37 +1577,75 @@ static int slub_nomerge;
1577 * requested a higher mininum order then we start with that one instead of 1577 * requested a higher mininum order then we start with that one instead of
1578 * the smallest order which will fit the object. 1578 * the smallest order which will fit the object.
1579 */ 1579 */
1580static int calculate_order(int size) 1580static inline int slab_order(int size, int min_objects,
1581 int max_order, int fract_leftover)
1581{ 1582{
1582 int order; 1583 int order;
1583 int rem; 1584 int rem;
1584 1585
1585 for (order = max(slub_min_order, fls(size - 1) - PAGE_SHIFT); 1586 for (order = max(slub_min_order,
1586 order < MAX_ORDER; order++) { 1587 fls(min_objects * size - 1) - PAGE_SHIFT);
1587 unsigned long slab_size = PAGE_SIZE << order; 1588 order <= max_order; order++) {
1588 1589
1589 if (order < slub_max_order && 1590 unsigned long slab_size = PAGE_SIZE << order;
1590 slab_size < slub_min_objects * size)
1591 continue;
1592 1591
1593 if (slab_size < size) 1592 if (slab_size < min_objects * size)
1594 continue; 1593 continue;
1595 1594
1596 if (order >= slub_max_order)
1597 break;
1598
1599 rem = slab_size % size; 1595 rem = slab_size % size;
1600 1596
1601 if (rem <= slab_size / 8) 1597 if (rem <= slab_size / fract_leftover)
1602 break; 1598 break;
1603 1599
1604 } 1600 }
1605 if (order >= MAX_ORDER)
1606 return -E2BIG;
1607 1601
1608 return order; 1602 return order;
1609} 1603}
1610 1604
1605static inline int calculate_order(int size)
1606{
1607 int order;
1608 int min_objects;
1609 int fraction;
1610
1611 /*
1612 * Attempt to find best configuration for a slab. This
1613 * works by first attempting to generate a layout with
1614 * the best configuration and backing off gradually.
1615 *
1616 * First we reduce the acceptable waste in a slab. Then
1617 * we reduce the minimum objects required in a slab.
1618 */
1619 min_objects = slub_min_objects;
1620 while (min_objects > 1) {
1621 fraction = 8;
1622 while (fraction >= 4) {
1623 order = slab_order(size, min_objects,
1624 slub_max_order, fraction);
1625 if (order <= slub_max_order)
1626 return order;
1627 fraction /= 2;
1628 }
1629 min_objects /= 2;
1630 }
1631
1632 /*
1633 * We were unable to place multiple objects in a slab. Now
1634 * lets see if we can place a single object there.
1635 */
1636 order = slab_order(size, 1, slub_max_order, 1);
1637 if (order <= slub_max_order)
1638 return order;
1639
1640 /*
1641 * Doh this slab cannot be placed using slub_max_order.
1642 */
1643 order = slab_order(size, 1, MAX_ORDER, 1);
1644 if (order <= MAX_ORDER)
1645 return order;
1646 return -ENOSYS;
1647}
1648
1611/* 1649/*
1612 * Figure out what the alignment of the objects will be. 1650 * Figure out what the alignment of the objects will be.
1613 */ 1651 */