[PATCH] node hotplug: register cpu: remove node struct
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Tue, 27 Jun 2006 09:53:41 +0000 (02:53 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 28 Jun 2006 00:32:37 +0000 (17:32 -0700)
With Goto-san's patch, we can add new pgdat/node at runtime.  I'm now
considering node-hot-add with cpu + memory on ACPI.

I found acpi container, which describes node, could evaluate cpu before
memory. This means cpu-hot-add occurs before memory hot add.

In most part, cpu-hot-add doesn't depend on node hot add.  But register_cpu(),
which creates symbolic link from node to cpu, requires that node should be
onlined before register_cpu().  When a node is onlined, its pgdat should be
there.

This patch-set holds off creating symbolic link from node to cpu
until node is onlined.

This removes node arguments from register_cpu().

Now, register_cpu() requires 'struct node' as its argument.  But the array of
struct node is now unified in driver/base/node.c now (By Goto's node hotplug
patch).  We can get struct node in generic way.  So, this argument is not
necessary now.

This patch also guarantees add cpu under node only when node is onlined.  It
is necessary for node-hot-add vs.  cpu-hot-add patch following this.

Moreover, register_cpu calculates cpu->node_id by cpu_to_node() without regard
to its 'struct node *root' argument.  This patch removes it.

Also modify callers of register_cpu()/unregister_cpu, whose args are changed
by register-cpu-remove-node-struct patch.

[Brice.Goglin@ens-lyon.org: fix it]
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Yasunori Goto <y-goto@jp.fujitsu.com>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Brice Goglin <Brice.Goglin@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
18 files changed:
arch/alpha/kernel/setup.c
arch/arm/kernel/setup.c
arch/i386/kernel/topology.c
arch/ia64/kernel/topology.c
arch/m32r/kernel/setup.c
arch/mips/kernel/smp.c
arch/parisc/kernel/topology.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/sysfs.c
arch/ppc/kernel/setup.c
arch/s390/kernel/smp.c
arch/sh/kernel/setup.c
arch/sh64/kernel/setup.c
arch/sparc64/kernel/setup.c
drivers/base/cpu.c
drivers/base/node.c
include/linux/cpu.h
include/linux/node.h

index 558b83368559396f4d50f793d37d8e7dd83c26d1..254c507a608c076f9e09aa8acb83edfea90d2975 100644 (file)
@@ -481,7 +481,7 @@ register_cpus(void)
                struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
                if (!p)
                        return -ENOMEM;
-               register_cpu(p, i, NULL);
+               register_cpu(p, i);
        }
        return 0;
 }
index 9fc9af88c60c72e54cad5e835c579b95027624e6..093ccba0503c9a1885bbddc3fa6f3c2e8a67e5eb 100644 (file)
@@ -808,7 +808,7 @@ static int __init topology_init(void)
        int cpu;
 
        for_each_possible_cpu(cpu)
-               register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL);
+               register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu);
 
        return 0;
 }
index 1eecc2e1bd4b0659f02b11741be330dbfb9d2ca3..e2e281d4bcc80ee7bc3b090e75914606231e6224 100644 (file)
 
 static struct i386_cpu cpu_devices[NR_CPUS];
 
-int arch_register_cpu(int num){
-       struct node *parent = NULL;
-
-#ifdef CONFIG_NUMA
-       int node = cpu_to_node(num);
-       if (node_online(node))
-               parent = &node_devices[parent_node(node)];
-#endif /* CONFIG_NUMA */
-
+int arch_register_cpu(int num)
+{
        /*
         * CPU0 cannot be offlined due to several
         * restrictions and assumptions in kernel. This basically
@@ -50,21 +43,13 @@ int arch_register_cpu(int num){
        if (!num)
                cpu_devices[num].cpu.no_control = 1;
 
-       return register_cpu(&cpu_devices[num].cpu, num, parent);
+       return register_cpu(&cpu_devices[num].cpu, num);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
 
 void arch_unregister_cpu(int num) {
-       struct node *parent = NULL;
-
-#ifdef CONFIG_NUMA
-       int node = cpu_to_node(num);
-       if (node_online(node))
-               parent = &node_devices[parent_node(node)];
-#endif /* CONFIG_NUMA */
-
-       return unregister_cpu(&cpu_devices[num].cpu, parent);
+       return unregister_cpu(&cpu_devices[num].cpu);
 }
 EXPORT_SYMBOL(arch_register_cpu);
 EXPORT_SYMBOL(arch_unregister_cpu);
index 42cb05bdc6807fecf655d0923348c7cba08c23f1..5737c9a061efc53366c54f5c9025fdb349acb151 100644 (file)
@@ -30,12 +30,6 @@ static struct ia64_cpu *sysfs_cpus;
 
 int arch_register_cpu(int num)
 {
-       struct node *parent = NULL;
-       
-#ifdef CONFIG_NUMA
-       parent = &node_devices[cpu_to_node(num)];
-#endif /* CONFIG_NUMA */
-
 #if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU)
        /*
         * If CPEI cannot be re-targetted, and this is
@@ -45,21 +39,14 @@ int arch_register_cpu(int num)
                sysfs_cpus[num].cpu.no_control = 1;
 #endif
 
-       return register_cpu(&sysfs_cpus[num].cpu, num, parent);
+       return register_cpu(&sysfs_cpus[num].cpu, num);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
 
 void arch_unregister_cpu(int num)
 {
-       struct node *parent = NULL;
-
-#ifdef CONFIG_NUMA
-       int node = cpu_to_node(num);
-       parent = &node_devices[node];
-#endif /* CONFIG_NUMA */
-
-       return unregister_cpu(&sysfs_cpus[num].cpu, parent);
+       return unregister_cpu(&sysfs_cpus[num].cpu);
 }
 EXPORT_SYMBOL(arch_register_cpu);
 EXPORT_SYMBOL(arch_unregister_cpu);
index 3cd3c2988a4875f6da0c8e2fb8af921264beba42..1ff483c8a4c9749c99d8f70b052ee9d805cc3aa6 100644 (file)
@@ -275,7 +275,7 @@ static int __init topology_init(void)
        int i;
 
        for_each_present_cpu(i)
-               register_cpu(&cpu_devices[i], i, NULL);
+               register_cpu(&cpu_devices[i], i);
 
        return 0;
 }
index 298f82fe8440a43d1a8140ed8a256d44595ed6d8..9096a5ea42298d4f409ce249f7f5e4ec3d9195c8 100644 (file)
@@ -446,7 +446,7 @@ static int __init topology_init(void)
        int ret;
 
        for_each_present_cpu(cpu) {
-               ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL);
+               ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu);
                if (ret)
                        printk(KERN_WARNING "topology_init: register_cpu %d "
                               "failed (%d)\n", cpu, ret);
index 3ba040050e4ca1d85a28448accea66e50a0ce0fb..068b20d822e7b9c672983135a0c038e11e491839 100644 (file)
@@ -26,11 +26,10 @@ static struct cpu cpu_devices[NR_CPUS] __read_mostly;
 
 static int __init topology_init(void)
 {
-       struct node *parent = NULL;
        int num;
 
        for_each_present_cpu(num) {
-               register_cpu(&cpu_devices[num], num, parent);
+               register_cpu(&cpu_devices[num], num);
        }
        return 0;
 }
index e5a44812441ac121b980e3d296f19e09651df045..0932a62a1c9637d6834c4872f7f5bca7e2b5d11d 100644 (file)
@@ -215,7 +215,7 @@ int __init ppc_init(void)
 
        /* register CPU devices */
        for_each_possible_cpu(i)
-               register_cpu(&cpu_devices[i], i, NULL);
+               register_cpu(&cpu_devices[i], i);
 
        /* call platform init */
        if (ppc_md.init != NULL) {
index 338491d1604aaf5b451d5cbc1b663b2901111ecd..412ad00e222d37c3dec0938a6847d03b6ef833bc 100644 (file)
@@ -348,23 +348,13 @@ static SYSDEV_ATTR(physical_id, 0444, show_physical_id, NULL);
 static int __init topology_init(void)
 {
        int cpu;
-       struct node *parent = NULL;
 
        register_nodes();
-
        register_cpu_notifier(&sysfs_cpu_nb);
 
        for_each_possible_cpu(cpu) {
                struct cpu *c = &per_cpu(cpu_devices, cpu);
 
-#ifdef CONFIG_NUMA
-               /* The node to which a cpu belongs can't be known
-                * until the cpu is made present.
-                */
-               parent = NULL;
-               if (cpu_present(cpu))
-                       parent = &node_devices[cpu_to_node(cpu)];
-#endif
                /*
                 * For now, we just see if the system supports making
                 * the RTAS calls for CPU hotplug.  But, there may be a
@@ -376,7 +366,7 @@ static int __init topology_init(void)
                        c->no_control = 1;
 
                if (cpu_online(cpu) || (c->no_control == 0)) {
-                       register_cpu(c, cpu, parent);
+                       register_cpu(c, cpu);
 
                        sysdev_create_file(&c->sysdev, &attr_physical_id);
                }
index 1f79e84ab464dd8a416eaab3d104e8aff11ea6d5..4b4607d89bfa6e1c105a01d85c0a674748c5fa8f 100644 (file)
@@ -475,7 +475,7 @@ int __init ppc_init(void)
 
        /* register CPU devices */
        for_each_possible_cpu(i)
-               register_cpu(&cpu_devices[i], i, NULL);
+               register_cpu(&cpu_devices[i], i);
 
        /* call platform init */
        if (ppc_md.init != NULL) {
index 343120c9223d798d6cad38703153df30f83e683b..8e03219eea76051f23d5f97edf5f61cab622ba38 100644 (file)
@@ -869,7 +869,7 @@ static int __init topology_init(void)
        int ret;
 
        for_each_possible_cpu(cpu) {
-               ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL);
+               ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu);
                if (ret)
                        printk(KERN_WARNING "topology_init: register_cpu %d "
                               "failed (%d)\n", cpu, ret);
index bb229ef030f3cbf70c5afa777cd50e194fed6025..9af22116c9a2b3a78e02c8533e59660769d95723 100644 (file)
@@ -402,7 +402,7 @@ static int __init topology_init(void)
        int cpu_id;
 
        for_each_possible_cpu(cpu_id)
-               register_cpu(&cpu[cpu_id], cpu_id, NULL);
+               register_cpu(&cpu[cpu_id], cpu_id);
 
        return 0;
 }
index d2711c9c9d13954dbadaecdf0665e7b3d06cdbe1..da98d8dbcf95324284de3d601e2364cc1923c896 100644 (file)
@@ -309,7 +309,7 @@ static struct cpu cpu[1];
 
 static int __init topology_init(void)
 {
-       return register_cpu(cpu, 0, NULL);
+       return register_cpu(cpu, 0);
 }
 
 subsys_initcall(topology_init);
index a6a7d8168346c6b50b9910727ccd344f9566b5f1..116d9632002defd035dfdae91f0d80767d75d3b6 100644 (file)
@@ -537,7 +537,7 @@ static int __init topology_init(void)
        for_each_possible_cpu(i) {
                struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
                if (p) {
-                       register_cpu(p, i, NULL);
+                       register_cpu(p, i);
                        err = 0;
                }
        }
index dd712b24ec91900f3b75506af6ecf6467f7ba160..3972d8ac9786872bfc2890152efbc52dd196bb9a 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/cpu.h>
 #include <linux/topology.h>
 #include <linux/device.h>
+#include <linux/node.h>
 
 #include "base.h"
 
@@ -57,13 +58,12 @@ static void __devinit register_cpu_control(struct cpu *cpu)
 {
        sysdev_create_file(&cpu->sysdev, &attr_online);
 }
-void unregister_cpu(struct cpu *cpu, struct node *root)
+void unregister_cpu(struct cpu *cpu)
 {
        int logical_cpu = cpu->sysdev.id;
 
-       if (root)
-               sysfs_remove_link(&root->sysdev.kobj,
-                                 kobject_name(&cpu->sysdev.kobj));
+       unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
+
        sysdev_remove_file(&cpu->sysdev, &attr_online);
 
        sysdev_unregister(&cpu->sysdev);
@@ -109,23 +109,21 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
  *
  * Initialize and register the CPU device.
  */
-int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
+int __devinit register_cpu(struct cpu *cpu, int num)
 {
        int error;
-
        cpu->node_id = cpu_to_node(num);
        cpu->sysdev.id = num;
        cpu->sysdev.cls = &cpu_sysdev_class;
 
        error = sysdev_register(&cpu->sysdev);
-       if (!error && root)
-               error = sysfs_create_link(&root->sysdev.kobj,
-                                         &cpu->sysdev.kobj,
-                                         kobject_name(&cpu->sysdev.kobj));
+
        if (!error && !cpu->no_control)
                register_cpu_control(cpu);
        if (!error)
                cpu_sys_devices[num] = &cpu->sysdev;
+       if (!error)
+               register_cpu_under_node(num, cpu_to_node(num));
 
 #ifdef CONFIG_KEXEC
        if (!error)
index cbd0f62b487015d82de2289a0d916435329da393..eae2bdc183bb7741a85c23f086d156c95b1d0317 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/cpumask.h>
 #include <linux/topology.h>
 #include <linux/nodemask.h>
+#include <linux/cpu.h>
 
 static struct sysdev_class node_class = {
        set_kset_name("node"),
@@ -192,9 +193,38 @@ void unregister_node(struct node *node)
 
 struct node node_devices[MAX_NUMNODES];
 
+/*
+ * register cpu under node
+ */
+int register_cpu_under_node(unsigned int cpu, unsigned int nid)
+{
+       if (node_online(nid)) {
+               struct sys_device *obj = get_cpu_sysdev(cpu);
+               if (!obj)
+                       return 0;
+               return sysfs_create_link(&node_devices[nid].sysdev.kobj,
+                                        &obj->kobj,
+                                        kobject_name(&obj->kobj));
+        }
+
+       return 0;
+}
+
+int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
+{
+       if (node_online(nid)) {
+               struct sys_device *obj = get_cpu_sysdev(cpu);
+               if (obj)
+                       sysfs_remove_link(&node_devices[nid].sysdev.kobj,
+                                        kobject_name(&obj->kobj));
+       }
+       return 0;
+}
+
 int register_one_node(int nid)
 {
        int error = 0;
+       int cpu;
 
        if (node_online(nid)) {
                int p_node = parent_node(nid);
@@ -204,6 +234,12 @@ int register_one_node(int nid)
                        parent = &node_devices[p_node];
 
                error = register_node(&node_devices[nid], nid, parent);
+
+               /* link cpu under this node */
+               for_each_present_cpu(cpu) {
+                       if (cpu_to_node(cpu) == nid)
+                               register_cpu_under_node(cpu, nid);
+               }
        }
 
        return error;
index 08d50c53aab401ef79c20e85213027d854e5d199..b23bf1c8addc535ca4ec245a6048dca66d5a2c4e 100644 (file)
@@ -31,10 +31,10 @@ struct cpu {
        struct sys_device sysdev;
 };
 
-extern int register_cpu(struct cpu *, int, struct node *);
+extern int register_cpu(struct cpu *cpu, int num);
 extern struct sys_device *get_cpu_sysdev(unsigned cpu);
 #ifdef CONFIG_HOTPLUG_CPU
-extern void unregister_cpu(struct cpu *, struct node *);
+extern void unregister_cpu(struct cpu *cpu);
 #endif
 struct notifier_block;
 
index 1e5347527fa8b0ac6464251b36cbbfd6b31e65d0..81dcec84cd8f00290037cb29c7f7e0960b51b895 100644 (file)
@@ -32,6 +32,19 @@ 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);
+#ifdef CONFIG_NUMA
+extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
+extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
+#else
+static inline int register_cpu_under_node(unsigned int cpu, unsigned int nid)
+{
+       return 0;
+}
+static inline int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
+{
+       return 0;
+}
+#endif
 
 #define to_node(sys_device) container_of(sys_device, struct node, sysdev)