From 7f4192f5d12c49cf72c39d8a2d46f638681fd014 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Tue, 28 Feb 2017 19:18:26 -0700 Subject: [PATCH] sparc64: create/destroy cpu sysfs dynamically Currently, cpu/cpuX represents maximum number of possible cpus in a domain. Those cpu sysfs directories also does not change as we add/remove cpus via ldom manager. Update sysfs so that it represents number of present cpus in the domain. As a result, cpu sysfs is also updated dynamically upon cpu add/removal. Orabug: 21775890 Orabug: 25216469 Before the fix: [root@ca-sparc76 ~]# ldm list NAME STATE FLAGS CONS VCPU MEMORY UTIL NORM UPTIME primary active -n-cv- UART 32 32G 0.2% 0.2% 11m [root@ca-sparc76 ~]# getconf _NPROCESSORS_CONF 512 [root@ca-sparc76 ~]# ldm set-vcpu 64 primary [root@ca-sparc76 ~]# ldm list NAME STATE FLAGS CONS VCPU MEMORY UTIL NORM UPTIME primary active -n-cv- UART 64 32G 0.0% 0.0% 12m [root@ca-sparc76 ~]# getconf _NPROCESSORS_CONF 512 ------------------------------------------------------------------------- After the fix: [root@ca-sparc76 ~]# getconf _NPROCESSORS_CONF 32 [root@ca-sparc76 ~]# ldm set-vcpu 64 primary [root@ca-sparc76 ~]# ldm list NAME STATE FLAGS CONS VCPU MEMORY UTIL NORM UPTIME primary active -n-cv- UART 64 32G 0.0% 0.0% 12m [root@ca-sparc76 ~]# getconf _NPROCESSORS_CONF 64 Signed-off-by: Atish Patra Reviewed-by: Konrad Rzeszutek Wilk Reviewed-by: Thomas Tai Signed-off-by: Allen Pais --- arch/sparc/include/asm/smp_64.h | 3 +++ arch/sparc/kernel/ds.c | 13 +++++++++++- arch/sparc/kernel/sysfs.c | 36 ++++++++++++++++++++++++--------- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/arch/sparc/include/asm/smp_64.h b/arch/sparc/include/asm/smp_64.h index ce2233f7e662..9e9af7662d62 100644 --- a/arch/sparc/include/asm/smp_64.h +++ b/arch/sparc/include/asm/smp_64.h @@ -63,6 +63,7 @@ void smp_release(void); #ifdef CONFIG_HOTPLUG_CPU int __cpu_disable(void); void __cpu_die(unsigned int cpu); +void arch_unregister_cpu(int cpu); #endif #endif /* !(__ASSEMBLY__) */ @@ -77,4 +78,6 @@ void __cpu_die(unsigned int cpu); #endif /* !(CONFIG_SMP) */ +void arch_register_cpu(int cpu); + #endif /* !(_SPARC64_SMP_H) */ diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index bd2bfbd7a3eb..0493d825d938 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -2014,13 +2015,18 @@ static int __cpuinit dr_cpu_configure(struct ds_dev *ds, resp_len, ncpus, mask, DR_CPU_STAT_CONFIGURED); - mdesc_populate_present_mask(mask); mdesc_fill_in_cpu_data(mask); for_each_cpu(cpu, mask) { int err; dprintk("ds-%llu: Starting cpu %d...\n", ds->id, cpu); + + cpu_maps_update_begin(); + set_cpu_present(cpu, true); + arch_register_cpu(cpu); + cpu_maps_update_done(); + err = cpu_up(cpu); if (err) { u32 res = DR_CPU_RES_FAILURE; @@ -2078,6 +2084,11 @@ static int dr_cpu_unconfigure(struct ds_dev *ds, dr_cpu_mark(resp, cpu, ncpus, DR_CPU_RES_FAILURE, DR_CPU_STAT_CONFIGURED); + + cpu_maps_update_begin(); + set_cpu_present(cpu, false); + arch_unregister_cpu(cpu); + cpu_maps_update_done(); } ds_cap_send(handle, resp, resp_len); diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c index aac0e6ca2b15..91805c7ad56a 100644 --- a/arch/sparc/kernel/sysfs.c +++ b/arch/sparc/kernel/sysfs.c @@ -487,6 +487,13 @@ static void unregister_cpu_online(unsigned int cpu) kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj)); kobject_put(cache_kobjs[cpu]); } + +void arch_unregister_cpu(int cpu) +{ + struct cpu *c = &per_cpu(cpu_devices, cpu); + + unregister_cpu(c); +} #endif static int sysfs_cpu_notify(struct notifier_block *self, @@ -535,6 +542,24 @@ static void register_nodes(void) #endif } +/* This function should only be called from the cpu_maps_update_begin + * or cpu_notifier_register_begin context. + */ +void arch_register_cpu(int cpu) +{ + int node = cpu_to_node(cpu); + struct cpu *c = &per_cpu(cpu_devices, cpu); + + if (!node_online(node)) + panic("corresponding node [%d] for cpu [%d] is not online.\n", + node, cpu); + + c->hotpluggable = 1; + register_cpu(c, cpu); + if (cpu_online(cpu)) + register_cpu_online(cpu); +} + static int __init topology_init(void) { int cpu; @@ -544,16 +569,9 @@ static int __init topology_init(void) check_mmu_stats(); cpu_notifier_register_begin(); - - for_each_possible_cpu(cpu) { - struct cpu *c = &per_cpu(cpu_devices, cpu); - - c->hotpluggable = 1; - register_cpu(c, cpu); - if (cpu_online(cpu)) - register_cpu_online(cpu); + for_each_present_cpu(cpu) { + arch_register_cpu(cpu); } - __register_cpu_notifier(&sysfs_cpu_nb); cpu_notifier_register_done(); -- 2.50.1