[PATCH] Register sysfs file for hotplugged new node
authorYasunori Goto <y-goto@jp.fujitsu.com>
Tue, 27 Jun 2006 09:53:38 +0000 (02:53 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 28 Jun 2006 00:32:36 +0000 (17:32 -0700)
When new node becomes enable by hot-add, new sysfs file must be created for
new node.  So, if new node is enabled by add_memory(), register_one_node() is
called to create it.  In addition, I386's arch_register_node() and a part of
register_nodes() of powerpc are consolidated to register_one_node() as a
generic_code().

This is tested by Tiger4(IPF) with node hot-plug emulation.

Signed-off-by: Keiichiro Tokunaga <tokuanga.keiich@jp.fujitsu.com>
Signed-off-by: Yasunori Goto <y-goto@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/i386/kernel/topology.c
arch/ia64/kernel/topology.c
arch/powerpc/kernel/sysfs.c
drivers/base/node.c
include/asm-i386/cpu.h
include/asm-i386/node.h [deleted file]
include/linux/node.h
mm/memory_hotplug.c

index 296355292c7c56433df1c849e93851985a7798d3..1eecc2e1bd4b0659f02b11741be330dbfb9d2ca3 100644 (file)
@@ -38,7 +38,7 @@ int arch_register_cpu(int num){
 #ifdef CONFIG_NUMA
        int node = cpu_to_node(num);
        if (node_online(node))
-               parent = &node_devices[node].node;
+               parent = &node_devices[parent_node(node)];
 #endif /* CONFIG_NUMA */
 
        /*
@@ -61,7 +61,7 @@ void arch_unregister_cpu(int num) {
 #ifdef CONFIG_NUMA
        int node = cpu_to_node(num);
        if (node_online(node))
-               parent = &node_devices[node].node;
+               parent = &node_devices[parent_node(node)];
 #endif /* CONFIG_NUMA */
 
        return unregister_cpu(&cpu_devices[num].cpu, parent);
@@ -74,16 +74,13 @@ EXPORT_SYMBOL(arch_unregister_cpu);
 
 #ifdef CONFIG_NUMA
 #include <linux/mmzone.h>
-#include <asm/node.h>
-
-struct i386_node node_devices[MAX_NUMNODES];
 
 static int __init topology_init(void)
 {
        int i;
 
        for_each_online_node(i)
-               arch_register_node(i);
+               register_one_node(i);
 
        for_each_present_cpu(i)
                arch_register_cpu(i);
index 879edb51d1e0e1b2c29698815127dc8b215f7067..42cb05bdc6807fecf655d0923348c7cba08c23f1 100644 (file)
@@ -26,9 +26,6 @@
 #include <asm/numa.h>
 #include <asm/cpu.h>
 
-#ifdef CONFIG_NUMA
-static struct node *sysfs_nodes;
-#endif
 static struct ia64_cpu *sysfs_cpus;
 
 int arch_register_cpu(int num)
@@ -36,7 +33,7 @@ int arch_register_cpu(int num)
        struct node *parent = NULL;
        
 #ifdef CONFIG_NUMA
-       parent = &sysfs_nodes[cpu_to_node(num)];
+       parent = &node_devices[cpu_to_node(num)];
 #endif /* CONFIG_NUMA */
 
 #if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU)
@@ -59,7 +56,7 @@ void arch_unregister_cpu(int num)
 
 #ifdef CONFIG_NUMA
        int node = cpu_to_node(num);
-       parent = &sysfs_nodes[node];
+       parent = &node_devices[node];
 #endif /* CONFIG_NUMA */
 
        return unregister_cpu(&sysfs_cpus[num].cpu, parent);
@@ -74,17 +71,11 @@ static int __init topology_init(void)
        int i, err = 0;
 
 #ifdef CONFIG_NUMA
-       sysfs_nodes = kzalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL);
-       if (!sysfs_nodes) {
-               err = -ENOMEM;
-               goto out;
-       }
-
        /*
         * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes?
         */
        for_each_online_node(i) {
-               if ((err = register_node(&sysfs_nodes[i], i, 0)))
+               if ((err = register_one_node(i)))
                        goto out;
        }
 #endif
index 5bc2585c8036d97e08b8fff0c174cce01ad61c14..338491d1604aaf5b451d5cbc1b663b2901111ecd 100644 (file)
@@ -304,23 +304,12 @@ static struct notifier_block sysfs_cpu_nb = {
 /* NUMA stuff */
 
 #ifdef CONFIG_NUMA
-static struct node node_devices[MAX_NUMNODES];
-
 static void register_nodes(void)
 {
        int i;
 
-       for (i = 0; i < MAX_NUMNODES; i++) {
-               if (node_online(i)) {
-                       int p_node = parent_node(i);
-                       struct node *parent = NULL;
-
-                       if (p_node != i)
-                               parent = &node_devices[p_node];
-
-                       register_node(&node_devices[i], i, parent);
-               }
-       }
+       for (i = 0; i < MAX_NUMNODES; i++)
+               register_one_node(i);
 }
 
 int sysfs_add_device_to_node(struct sys_device *dev, int nid)
index c80c3aeed004a558de9cf9db0632191cf1c16c99..cbd0f62b487015d82de2289a0d916435329da393 100644 (file)
@@ -190,6 +190,31 @@ void unregister_node(struct node *node)
        sysdev_unregister(&node->sysdev);
 }
 
+struct node node_devices[MAX_NUMNODES];
+
+int register_one_node(int nid)
+{
+       int error = 0;
+
+       if (node_online(nid)) {
+               int p_node = parent_node(nid);
+               struct node *parent = NULL;
+
+               if (p_node != nid)
+                       parent = &node_devices[p_node];
+
+               error = register_node(&node_devices[nid], nid, parent);
+       }
+
+       return error;
+
+}
+
+void unregister_one_node(int nid)
+{
+       unregister_node(&node_devices[nid]);
+}
+
 static int __init register_node_type(void)
 {
        return sysdev_class_register(&node_class);
index e7252c216ca81cc8d6543f51b51fa1f8a216d194..b1bc7b1b64b0e304d13f907e4d5cd607417bdfee 100644 (file)
@@ -7,8 +7,6 @@
 #include <linux/nodemask.h>
 #include <linux/percpu.h>
 
-#include <asm/node.h>
-
 struct i386_cpu {
        struct cpu cpu;
 };
diff --git a/include/asm-i386/node.h b/include/asm-i386/node.h
deleted file mode 100644 (file)
index e13c6ff..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _ASM_I386_NODE_H_
-#define _ASM_I386_NODE_H_
-
-#include <linux/device.h>
-#include <linux/mmzone.h>
-#include <linux/node.h>
-#include <linux/topology.h>
-#include <linux/nodemask.h>
-
-struct i386_node {
-       struct node node;
-};
-extern struct i386_node node_devices[MAX_NUMNODES];
-
-static inline int arch_register_node(int num){
-       int p_node;
-       struct node *parent = NULL;
-
-       if (!node_online(num))
-               return 0;
-       p_node = parent_node(num);
-
-       if (p_node != num)
-               parent = &node_devices[p_node].node;
-
-       return register_node(&node_devices[num].node, num, parent);
-}
-
-#endif /* _ASM_I386_NODE_H_ */
index 254dc3de650b81e5cce4821f8101dad72005f996..1e5347527fa8b0ac6464251b36cbbfd6b31e65d0 100644 (file)
@@ -26,8 +26,12 @@ struct node {
        struct sys_device       sysdev;
 };
 
+extern struct node node_devices[];
+
 extern int register_node(struct node *, int, struct node *);
 extern void unregister_node(struct node *node);
+extern int register_one_node(int nid);
+extern void unregister_one_node(int nid);
 
 #define to_node(sys_device) container_of(sys_device, struct node, sysdev)
 
index f13783e81eb6b8caefac5854477a3f0a096716cf..ea4038838b0a2b4c95a46cc3d4f1eaad25556f5f 100644 (file)
@@ -256,9 +256,19 @@ int add_memory(int nid, u64 start, u64 size)
        if (ret < 0)
                goto error;
 
-       /* we online node here. we have no error path from here. */
+       /* we online node here. we can't roll back from here. */
        node_set_online(nid);
 
+       if (new_pgdat) {
+               ret = register_one_node(nid);
+               /*
+                * If sysfs file of new node can't create, cpu on the node
+                * can't be hot-added. There is no rollback way now.
+                * So, check by BUG_ON() to catch it reluctantly..
+                */
+               BUG_ON(ret);
+       }
+
        /* register this memory as resource */
        register_memory_resource(start, size);