diff options
| author | Len Brown <len.brown@intel.com> | 2004-10-27 19:41:43 -0400 |
|---|---|---|
| committer | Len Brown <lenb@dhcppc3.> | 2004-10-27 19:41:43 -0400 |
| commit | 88a664ec70b650ef6d00a47c63776ae27416c23e (patch) | |
| tree | 1e0d292143c183e54cfb2c352af06a0294554cdf | |
| parent | fd613a86b7f6c884d36a888a63739df449e7eed0 (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.c | 31 | ||||
| -rw-r--r-- | arch/ia64/dig/Makefile | 5 | ||||
| -rw-r--r-- | arch/ia64/dig/topology.c | 43 | ||||
| -rw-r--r-- | arch/ia64/kernel/Makefile | 3 | ||||
| -rw-r--r-- | arch/ia64/kernel/topology.c | 90 | ||||
| -rw-r--r-- | arch/ia64/mm/numa.c | 36 | ||||
| -rw-r--r-- | drivers/base/cpu.c | 20 | ||||
| -rw-r--r-- | include/asm-i386/cpu.h | 17 | ||||
| -rw-r--r-- | include/asm-ia64/cpu.h | 5 | ||||
| -rw-r--r-- | include/linux/cpu.h | 3 |
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 |
