diff options
Diffstat (limited to 'mm/slub.c')
-rw-r--r-- | mm/slub.c | 66 |
1 files changed, 52 insertions, 14 deletions
@@ -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 | */ |
1580 | static int calculate_order(int size) | 1580 | static 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 | ||
1605 | static 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 | */ |