]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sparc64: create/destroy cpu sysfs dynamically
authorAtish Patra <atish.patra@oracle.com>
Wed, 1 Mar 2017 02:18:26 +0000 (19:18 -0700)
committerChuck Anderson <chuck.anderson@oracle.com>
Thu, 6 Apr 2017 07:13:44 +0000 (00:13 -0700)
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 <atish.patra@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Thomas Tai <thomas.tai@oracle.com>
Signed-off-by: Allen Pais <allen.pais@oracle.com>
arch/sparc/include/asm/smp_64.h
arch/sparc/kernel/ds.c
arch/sparc/kernel/sysfs.c

index ce2233f7e662d7f85f5a32ea45339f0eda67e19c..9e9af7662d62ab706c38d76eaf63c5de1259f720 100644 (file)
@@ -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) */
index bd2bfbd7a3eb6894422caee3c168a49691b74bdb..0493d825d938e4d2924b6c41ffe970921d366db9 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/suspend.h>
 #include <linux/syscore_ops.h>
 #include <linux/stop_machine.h>
+#include <linux/cpu.h>
 
 #include <asm/hypervisor.h>
 #include <asm/ldc.h>
@@ -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);
index aac0e6ca2b1527baccb3e25f2335d25f2b0b6441..91805c7ad56a37b69722ab5b834f0e9af4e47ba3 100644 (file)
@@ -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();