summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2004-10-27 19:41:43 -0400
committerLen Brown <lenb@dhcppc3.>2004-10-27 19:41:43 -0400
commit88a664ec70b650ef6d00a47c63776ae27416c23e (patch)
tree1e0d292143c183e54cfb2c352af06a0294554cdf
parentfd613a86b7f6c884d36a888a63739df449e7eed0 (diff)
IA64 CPU hotplug topology
Extend support for dynamic registration and unregistration of the cpu, by implementing and exporting arch_register_cpu()/arch_unregister_cpu(). Also combine multiple implementation of topology_init() functions to single topology_init() in case of ia64 architecture. Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--arch/i386/mach-default/topology.c31
-rw-r--r--arch/ia64/dig/Makefile5
-rw-r--r--arch/ia64/dig/topology.c43
-rw-r--r--arch/ia64/kernel/Makefile3
-rw-r--r--arch/ia64/kernel/topology.c90
-rw-r--r--arch/ia64/mm/numa.c36
-rw-r--r--drivers/base/cpu.c20
-rw-r--r--include/asm-i386/cpu.h17
-rw-r--r--include/asm-ia64/cpu.h5
-rw-r--r--include/linux/cpu.h3
10 files changed, 153 insertions, 100 deletions
diff --git a/arch/i386/mach-default/topology.c b/arch/i386/mach-default/topology.c
index 37bfa9144c8b..8e4f0ab374e4 100644
--- a/arch/i386/mach-default/topology.c
+++ b/arch/i386/mach-default/topology.c
@@ -32,6 +32,37 @@
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[node].node;
+#endif /* CONFIG_NUMA */
+
+ return register_cpu(&cpu_devices[num].cpu, num, parent);
+}
+
+#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[node].node;
+#endif /* CONFIG_NUMA */
+
+ return unregister_cpu(&cpu_devices[num].cpu, parent);
+}
+EXPORT_SYMBOL(arch_register_cpu);
+EXPORT_SYMBOL(arch_unregister_cpu);
+#endif /*CONFIG_HOTPLUG_CPU*/
+
+
+
#ifdef CONFIG_NUMA
#include <linux/mmzone.h>
#include <asm/node.h>
diff --git a/arch/ia64/dig/Makefile b/arch/ia64/dig/Makefile
index 1a7f925ea19e..971cd7870dd4 100644
--- a/arch/ia64/dig/Makefile
+++ b/arch/ia64/dig/Makefile
@@ -6,9 +6,4 @@
#
obj-y := setup.o
-
-ifndef CONFIG_NUMA
-obj-$(CONFIG_IA64_DIG) += topology.o
-endif
-
obj-$(CONFIG_IA64_GENERIC) += machvec.o
diff --git a/arch/ia64/dig/topology.c b/arch/ia64/dig/topology.c
deleted file mode 100644
index 8dc31378bb1c..000000000000
--- a/arch/ia64/dig/topology.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * arch/ia64/dig/topology.c
- * Popuate driverfs with topology information.
- * Derived entirely from i386/mach-default.c
- * Intel Corporation - Ashok Raj
- */
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/cpumask.h>
-#include <linux/percpu.h>
-#include <linux/notifier.h>
-#include <linux/cpu.h>
-#include <asm/cpu.h>
-
-static DEFINE_PER_CPU(struct ia64_cpu, cpu_devices);
-
-/*
- * First Pass: simply borrowed code for now. Later should hook into
- * hotplug notification for node/cpu/memory as applicable
- */
-
-static int arch_register_cpu(int num)
-{
- struct node *parent = NULL;
-
-#ifdef CONFIG_NUMA
- //parent = &node_devices[cpu_to_node(num)].node;
-#endif
-
- return register_cpu(&per_cpu(cpu_devices,num).cpu, num, parent);
-}
-
-static int __init topology_init(void)
-{
- int i;
-
- for_each_cpu(i) {
- arch_register_cpu(i);
- }
- return 0;
-}
-
-subsys_initcall(topology_init);
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index fbf5caca4663..12d8bf976cc2 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -6,7 +6,8 @@ extra-y := head.o init_task.o vmlinux.lds
obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \
irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \
- salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o unwind.o mca.o mca_asm.o
+ salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
+ unwind.o mca.o mca_asm.o topology.o
obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
new file mode 100644
index 000000000000..aba0ea358b4a
--- /dev/null
+++ b/arch/ia64/kernel/topology.c
@@ -0,0 +1,90 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * This file contains NUMA specific variables and functions which can
+ * be split away from DISCONTIGMEM and are used on NUMA machines with
+ * contiguous memory.
+ * 2002/08/07 Erich Focht <efocht@ess.nec.de>
+ * Populate cpu entries in sysfs for non-numa systems as well
+ * Intel Corporation - Ashok Raj
+ */
+
+#include <linux/config.h>
+#include <linux/cpu.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/node.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <asm/mmzone.h>
+#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)
+{
+ struct node *parent = NULL;
+
+#ifdef CONFIG_NUMA
+ parent = &sysfs_nodes[cpu_to_node(num)];
+#endif /* CONFIG_NUMA */
+
+ return register_cpu(&sysfs_cpus[num].cpu, num, parent);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+void arch_unregister_cpu(int num)
+{
+ struct node *parent = NULL;
+
+#ifdef CONFIG_NUMA
+ int node = cpu_to_node(num);
+ parent = &sysfs_nodes[node];
+#endif /* CONFIG_NUMA */
+
+ return unregister_cpu(&sysfs_cpus[num].cpu, parent);
+}
+EXPORT_SYMBOL(arch_register_cpu);
+EXPORT_SYMBOL(arch_unregister_cpu);
+#endif /*CONFIG_HOTPLUG_CPU*/
+
+
+static int __init topology_init(void)
+{
+ int i, err = 0;
+
+#ifdef CONFIG_NUMA
+ sysfs_nodes = kmalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL);
+ if (!sysfs_nodes) {
+ err = -ENOMEM;
+ goto out;
+ }
+ memset(sysfs_nodes, 0, sizeof(struct node) * MAX_NUMNODES);
+
+ for (i = 0; i < numnodes; i++)
+ if ((err = register_node(&sysfs_nodes[i], i, 0)))
+ goto out;
+#endif
+
+ sysfs_cpus = kmalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL);
+ if (!sysfs_cpus) {
+ err = -ENOMEM;
+ goto out;
+ }
+ memset(sysfs_cpus, 0, sizeof(struct ia64_cpu) * NR_CPUS);
+
+ for_each_present_cpu(i)
+ if((err = arch_register_cpu(i)))
+ goto out;
+out:
+ return err;
+}
+
+__initcall(topology_init);
diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c
index 9e5eee13a4c0..77118bbf3d8b 100644
--- a/arch/ia64/mm/numa.c
+++ b/arch/ia64/mm/numa.c
@@ -20,8 +20,6 @@
#include <asm/mmzone.h>
#include <asm/numa.h>
-static struct node *sysfs_nodes;
-static struct cpu *sysfs_cpus;
/*
* The following structures are usually initialized by ACPI or
@@ -49,37 +47,3 @@ paddr_to_nid(unsigned long paddr)
return (i < num_node_memblks) ? node_memblk[i].nid : (num_node_memblks ? -1 : 0);
}
-
-static int __init topology_init(void)
-{
- int i, err = 0;
-
- sysfs_nodes = kmalloc(sizeof(struct node) * numnodes, GFP_KERNEL);
- if (!sysfs_nodes) {
- err = -ENOMEM;
- goto out;
- }
- memset(sysfs_nodes, 0, sizeof(struct node) * numnodes);
-
- sysfs_cpus = kmalloc(sizeof(struct cpu) * NR_CPUS, GFP_KERNEL);
- if (!sysfs_cpus) {
- kfree(sysfs_nodes);
- err = -ENOMEM;
- goto out;
- }
- memset(sysfs_cpus, 0, sizeof(struct cpu) * NR_CPUS);
-
- for (i = 0; i < numnodes; i++)
- if ((err = register_node(&sysfs_nodes[i], i, NULL)))
- goto out;
-
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_online(i))
- if((err = register_cpu(&sysfs_cpus[i], i,
- &sysfs_nodes[cpu_to_node(i)])))
- goto out;
- out:
- return err;
-}
-
-__initcall(topology_init);
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 42f4337f9627..8fb216f575f3 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -48,10 +48,23 @@ static ssize_t store_online(struct sys_device *dev, const char *buf,
}
static SYSDEV_ATTR(online, 0600, show_online, store_online);
-static void __init register_cpu_control(struct cpu *cpu)
+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)
+{
+
+ if (root)
+ sysfs_remove_link(&root->sysdev.kobj,
+ kobject_name(&cpu->sysdev.kobj));
+ sysdev_remove_file(&cpu->sysdev, &attr_online);
+
+ sysdev_unregister(&cpu->sysdev);
+
+ return;
+}
+EXPORT_SYMBOL(unregister_cpu);
#else /* ... !CONFIG_HOTPLUG_CPU */
static inline void register_cpu_control(struct cpu *cpu)
{
@@ -66,7 +79,7 @@ static inline void register_cpu_control(struct cpu *cpu)
*
* Initialize and register the CPU device.
*/
-int __init register_cpu(struct cpu *cpu, int num, struct node *root)
+int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
{
int error;
@@ -83,6 +96,9 @@ int __init register_cpu(struct cpu *cpu, int num, struct node *root)
register_cpu_control(cpu);
return error;
}
+#ifdef CONFIG_HOTPLUG_CPU
+EXPORT_SYMBOL(register_cpu);
+#endif
diff --git a/include/asm-i386/cpu.h b/include/asm-i386/cpu.h
index c5d591e4902b..a2e581ffc91f 100644
--- a/include/asm-i386/cpu.h
+++ b/include/asm-i386/cpu.h
@@ -12,18 +12,9 @@ struct i386_cpu {
struct cpu cpu;
};
extern struct i386_cpu cpu_devices[NR_CPUS];
-
-
-static inline 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[node].node;
-#endif /* CONFIG_NUMA */
-
- return register_cpu(&cpu_devices[num].cpu, num, parent);
-}
+extern int arch_register_cpu(int num);
+#ifdef CONFIG_HOTPLUG_CPU
+extern void arch_unregister_cpu(int);
+#endif
#endif /* _ASM_I386_CPU_H_ */
diff --git a/include/asm-ia64/cpu.h b/include/asm-ia64/cpu.h
index 33c5d0fe9e85..e87fa3210a2b 100644
--- a/include/asm-ia64/cpu.h
+++ b/include/asm-ia64/cpu.h
@@ -14,4 +14,9 @@ DECLARE_PER_CPU(struct ia64_cpu, cpu_devices);
DECLARE_PER_CPU(int, cpu_state);
+extern int arch_register_cpu(int num);
+#ifdef CONFIG_HOTPLUG_CPU
+extern void arch_unregister_cpu(int);
+#endif
+
#endif /* _ASM_IA64_CPU_H_ */
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 7130cef0f137..fe0298e5dae1 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -32,6 +32,9 @@ struct cpu {
};
extern int register_cpu(struct cpu *, int, struct node *);
+#ifdef CONFIG_HOTPLUG_CPU
+extern void unregister_cpu(struct cpu *, struct node *);
+#endif
struct notifier_block;
#ifdef CONFIG_SMP