aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-07-16 02:38:15 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 12:05:36 -0400
commitb71636e29823c0602d908a2a62e94c9b57a97491 (patch)
treed69a20eec2cc05bcd9b0dac2b9d4ccd9bad39e09
parentf0630fff54a239efbbd89faf6a62da071ef1ff78 (diff)
numa: mempolicy: dynamic interleave map for system init
This converts the default system init memory policy to use a dynamically created node map instead of defaulting to all online nodes. Nodes of a certain size (>= 16MB) are judged to be suitable for interleave, and are added to the map. If all nodes are smaller in size, the largest one is automatically selected. Without this, tiny nodes find themselves out of memory before we even make it to userspace. Systems with large nodes will notice no change. Only the system init policy is effected by this change, the regular MPOL_DEFAULT policy is still switched to later on in the boot process as normal. Signed-off-by: Paul Mundt <lethal@linux-sh.org> Cc: Andi Kleen <ak@suse.de> Cc: Christoph Lameter <clameter@sgi.com> Cc: Hugh Dickins <hugh@veritas.com> Cc: Lee Schermerhorn <lee.schermerhorn@hp.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/mempolicy.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index d76e8eb342d0..a67c8f1828ac 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1597,6 +1597,10 @@ void mpol_free_shared_policy(struct shared_policy *p)
1597/* assumes fs == KERNEL_DS */ 1597/* assumes fs == KERNEL_DS */
1598void __init numa_policy_init(void) 1598void __init numa_policy_init(void)
1599{ 1599{
1600 nodemask_t interleave_nodes;
1601 unsigned long largest = 0;
1602 int nid, prefer = 0;
1603
1600 policy_cache = kmem_cache_create("numa_policy", 1604 policy_cache = kmem_cache_create("numa_policy",
1601 sizeof(struct mempolicy), 1605 sizeof(struct mempolicy),
1602 0, SLAB_PANIC, NULL, NULL); 1606 0, SLAB_PANIC, NULL, NULL);
@@ -1605,10 +1609,31 @@ void __init numa_policy_init(void)
1605 sizeof(struct sp_node), 1609 sizeof(struct sp_node),
1606 0, SLAB_PANIC, NULL, NULL); 1610 0, SLAB_PANIC, NULL, NULL);
1607 1611
1608 /* Set interleaving policy for system init. This way not all 1612 /*
1609 the data structures allocated at system boot end up in node zero. */ 1613 * Set interleaving policy for system init. Interleaving is only
1614 * enabled across suitably sized nodes (default is >= 16MB), or
1615 * fall back to the largest node if they're all smaller.
1616 */
1617 nodes_clear(interleave_nodes);
1618 for_each_online_node(nid) {
1619 unsigned long total_pages = node_present_pages(nid);
1620
1621 /* Preserve the largest node */
1622 if (largest < total_pages) {
1623 largest = total_pages;
1624 prefer = nid;
1625 }
1626
1627 /* Interleave this node? */
1628 if ((total_pages << PAGE_SHIFT) >= (16 << 20))
1629 node_set(nid, interleave_nodes);
1630 }
1631
1632 /* All too small, use the largest */
1633 if (unlikely(nodes_empty(interleave_nodes)))
1634 node_set(prefer, interleave_nodes);
1610 1635
1611 if (do_set_mempolicy(MPOL_INTERLEAVE, &node_online_map)) 1636 if (do_set_mempolicy(MPOL_INTERLEAVE, &interleave_nodes))
1612 printk("numa_policy_init: interleaving failed\n"); 1637 printk("numa_policy_init: interleaving failed\n");
1613} 1638}
1614 1639