cpusets: randomize node rotor used in cpuset_mem_spread_node()
[safe/jmp/linux-2.6] / arch / x86 / mm / numa.c
index f3a19e9..10c27bb 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/topology.h>
 #include <linux/module.h>
 #include <linux/bootmem.h>
+#include <linux/random.h>
 
 #ifdef CONFIG_DEBUG_PER_CPU_MAPS
 # define DBG(x...) printk(KERN_DEBUG x)
@@ -12,7 +13,7 @@
 /*
  * Which logical CPUs are on which nodes
  */
-cpumask_t *node_to_cpumask_map;
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
 EXPORT_SYMBOL(node_to_cpumask_map);
 
 /*
@@ -25,7 +26,6 @@ EXPORT_SYMBOL(node_to_cpumask_map);
 void __init setup_node_to_cpumask_map(void)
 {
        unsigned int node, num = 0;
-       cpumask_t *map;
 
        /* setup nr_node_ids if not done yet */
        if (nr_node_ids == MAX_NUMNODES) {
@@ -35,29 +35,19 @@ void __init setup_node_to_cpumask_map(void)
        }
 
        /* allocate the map */
-       map = alloc_bootmem_low(nr_node_ids * sizeof(cpumask_t));
-       DBG("node_to_cpumask_map at %p for %d nodes\n", map, nr_node_ids);
+       for (node = 0; node < nr_node_ids; node++)
+               alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
 
-       pr_debug("Node to cpumask map at %p for %d nodes\n",
-                map, nr_node_ids);
-
-       /* node_to_cpumask() will now work */
-       node_to_cpumask_map = map;
+       /* cpumask_of_node() will now work */
+       pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
 }
 
 #ifdef CONFIG_DEBUG_PER_CPU_MAPS
 /*
  * Returns a pointer to the bitmask of CPUs on Node 'node'.
  */
-const cpumask_t *cpumask_of_node(int node)
+const struct cpumask *cpumask_of_node(int node)
 {
-       if (node_to_cpumask_map == NULL) {
-               printk(KERN_WARNING
-                       "cpumask_of_node(%d): no node_to_cpumask_map!\n",
-                       node);
-               dump_stack();
-               return cpu_online_mask;
-       }
        if (node >= nr_node_ids) {
                printk(KERN_WARNING
                        "cpumask_of_node(%d): node > nr_node_ids(%d)\n",
@@ -65,7 +55,30 @@ const cpumask_t *cpumask_of_node(int node)
                dump_stack();
                return cpu_none_mask;
        }
-       return &node_to_cpumask_map[node];
+       if (node_to_cpumask_map[node] == NULL) {
+               printk(KERN_WARNING
+                       "cpumask_of_node(%d): no node_to_cpumask_map!\n",
+                       node);
+               dump_stack();
+               return cpu_online_mask;
+       }
+       return node_to_cpumask_map[node];
 }
 EXPORT_SYMBOL(cpumask_of_node);
 #endif
+
+/*
+ * Return the bit number of a random bit set in the nodemask.
+ *   (returns -1 if nodemask is empty)
+ */
+int __node_random(const nodemask_t *maskp)
+{
+       int w, bit = -1;
+
+       w = nodes_weight(*maskp);
+       if (w)
+               bit = bitmap_ord_to_pos(maskp->bits,
+                       get_random_int() % w, MAX_NUMNODES);
+       return bit;
+}
+EXPORT_SYMBOL(__node_random);