x86: add check for node passed to node_to_cpumask, v3
authorMike Travis <travis@sgi.com>
Fri, 27 Jun 2008 17:10:13 +0000 (10:10 -0700)
committerIngo Molnar <mingo@elte.hu>
Tue, 8 Jul 2008 11:16:16 +0000 (13:16 +0200)
  * When CONFIG_DEBUG_PER_CPU_MAPS is set, the node passed to
    node_to_cpumask and node_to_cpumask_ptr should be validated.
    If invalid, then a dump_stack is performed and a zero cpumask
    is returned.

v2: Slightly different version to remove a compiler warning.
v3: Redone to reflect moving setup.c -> setup_percpu.c

Signed-off-by: Mike Travis <travis@sgi.com>
Cc: Vegard Nossum <vegard.nossum@gmail.com>
Cc: "akpm@linux-foundation.org" <akpm@linux-foundation.org>
Cc: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/setup_percpu.c
include/asm-x86/topology.h

index 7068f95cccc652ce763061e1f811cbb5f1ba0510..43aca2de624a6ec06746b20b50562f6113be8cbd 100644 (file)
@@ -346,6 +346,10 @@ int early_cpu_to_node(int cpu)
        return per_cpu(x86_cpu_to_node_map, cpu);
 }
 
+
+/* empty cpumask */
+static const cpumask_t cpu_mask_none;
+
 /*
  * Returns a pointer to the bitmask of CPUs on Node 'node'.
  */
@@ -358,13 +362,23 @@ cpumask_t *_node_to_cpumask_ptr(int node)
                dump_stack();
                return &cpu_online_map;
        }
-       BUG_ON(node >= nr_node_ids);
-       return &node_to_cpumask_map[node];
+       if (node >= nr_node_ids) {
+               printk(KERN_WARNING
+                       "_node_to_cpumask_ptr(%d): node > nr_node_ids(%d)\n",
+                       node, nr_node_ids);
+               dump_stack();
+               return (cpumask_t *)&cpu_mask_none;
+       }
+       return (cpumask_t *)&node_to_cpumask_map[node];
 }
 EXPORT_SYMBOL(_node_to_cpumask_ptr);
 
 /*
  * Returns a bitmask of CPUs on Node 'node'.
+ *
+ * Side note: this function creates the returned cpumask on the stack
+ * so with a high NR_CPUS count, excessive stack space is used.  The
+ * node_to_cpumask_ptr function should be used whenever possible.
  */
 cpumask_t node_to_cpumask(int node)
 {
@@ -374,7 +388,13 @@ cpumask_t node_to_cpumask(int node)
                dump_stack();
                return cpu_online_map;
        }
-       BUG_ON(node >= nr_node_ids);
+       if (node >= nr_node_ids) {
+               printk(KERN_WARNING
+                       "node_to_cpumask(%d): node > nr_node_ids(%d)\n",
+                       node, nr_node_ids);
+               dump_stack();
+               return cpu_mask_none;
+       }
        return node_to_cpumask_map[node];
 }
 EXPORT_SYMBOL(node_to_cpumask);
index 1f97758de4ab70b4ebbe4ae443132eaa11c547c7..98e5f17ea85634003407dc0c363faf25147c4225 100644 (file)
@@ -57,7 +57,12 @@ static inline int cpu_to_node(int cpu)
 }
 #define early_cpu_to_node(cpu) cpu_to_node(cpu)
 
-/* Returns a bitmask of CPUs on Node 'node'. */
+/* Returns a bitmask of CPUs on Node 'node'.
+ *
+ * Side note: this function creates the returned cpumask on the stack
+ * so with a high NR_CPUS count, excessive stack space is used.  The
+ * node_to_cpumask_ptr function should be used whenever possible.
+ */
 static inline cpumask_t node_to_cpumask(int node)
 {
        return node_to_cpumask_map[node];