]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/smp: Switch to GENERIC_CPU_DEVICES
authorSven Schnelle <svens@linux.ibm.com>
Wed, 3 Jul 2024 08:11:59 +0000 (10:11 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Wed, 10 Jul 2024 17:50:44 +0000 (19:50 +0200)
Instead of setting up non-boot CPUs early in architecture code,
only setup the cpu present mask and let the generic code handle
cpu bringup.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/Kconfig
arch/s390/include/asm/smp.h
arch/s390/kernel/smp.c
drivers/s390/char/sclp_config.c

index 9788ae5e930b5d5d8dd9508c4681ee6af3c21543..371c2bf881493a2cc0b037b3b69bcedd96db4d67 100644 (file)
@@ -142,6 +142,7 @@ config S390
        select FUNCTION_ALIGNMENT_8B if CC_IS_GCC
        select FUNCTION_ALIGNMENT_16B if !CC_IS_GCC
        select GENERIC_ALLOCATOR
+       select GENERIC_CPU_DEVICES
        select GENERIC_CPU_AUTOPROBE
        select GENERIC_CPU_VULNERABILITIES
        select GENERIC_ENTRY
index 0b1ed637bfd62ad8e2fe140a79266e5efa135506..c13c79025348c39a9e18269bbb8d746e597fe6f7 100644 (file)
@@ -59,7 +59,7 @@ static inline void smp_cpus_done(unsigned int max_cpus)
 {
 }
 
-extern int smp_rescan_cpus(void);
+extern int smp_rescan_cpus(bool early);
 extern void __noreturn cpu_die(void);
 extern void __cpu_die(unsigned int cpu);
 extern int __cpu_disable(void);
index 4c2faab56eb6b878fca6fbb489a963091fb722cb..c3c54adf67bc23a7683376558ad6425cb4cb8cbc 100644 (file)
@@ -74,8 +74,6 @@ enum {
        CPU_STATE_CONFIGURED,
 };
 
-static DEFINE_PER_CPU(struct cpu *, cpu_device);
-
 struct pcpu {
        unsigned long ec_mask;          /* bit mask for ec_xxx functions */
        unsigned long ec_clk;           /* sigp timestamp for ec_xxx */
@@ -719,8 +717,6 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early)
        }
 }
 
-static int smp_add_present_cpu(int cpu);
-
 static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail,
                        bool configured, bool early)
 {
@@ -744,7 +740,7 @@ static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail,
                        pcpu->state = CPU_STATE_STANDBY;
                smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
                set_cpu_present(cpu, true);
-               if (!early && smp_add_present_cpu(cpu) != 0)
+               if (!early && arch_register_cpu(cpu))
                        set_cpu_present(cpu, false);
                else
                        nr++;
@@ -831,9 +827,6 @@ void __init smp_detect_cpus(void)
                        s_cpus += smp_cpu_mtid + 1;
        }
        pr_info("%d configured CPUs, %d standby CPUs\n", c_cpus, s_cpus);
-
-       /* Add CPUs present at boot */
-       __smp_rescan_cpus(info, true);
        memblock_free(info, sizeof(*info));
 }
 
@@ -974,6 +967,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        if (register_external_irq(EXT_IRQ_EXTERNAL_CALL, do_ext_call_interrupt))
                panic("Couldn't request external interrupt 0x1202");
        system_ctl_set_bit(0, 13);
+       smp_rescan_cpus(true);
 }
 
 void __init smp_prepare_boot_cpu(void)
@@ -1111,35 +1105,34 @@ static struct attribute_group cpu_online_attr_group = {
 
 static int smp_cpu_online(unsigned int cpu)
 {
-       struct device *s = &per_cpu(cpu_device, cpu)->dev;
+       struct cpu *c = &per_cpu(cpu_devices, cpu);
 
-       return sysfs_create_group(&s->kobj, &cpu_online_attr_group);
+       return sysfs_create_group(&c->dev.kobj, &cpu_online_attr_group);
 }
 
 static int smp_cpu_pre_down(unsigned int cpu)
 {
-       struct device *s = &per_cpu(cpu_device, cpu)->dev;
+       struct cpu *c = &per_cpu(cpu_devices, cpu);
 
-       sysfs_remove_group(&s->kobj, &cpu_online_attr_group);
+       sysfs_remove_group(&c->dev.kobj, &cpu_online_attr_group);
        return 0;
 }
 
-static int smp_add_present_cpu(int cpu)
+bool arch_cpu_is_hotpluggable(int cpu)
 {
-       struct device *s;
-       struct cpu *c;
+       return !!cpu;
+}
+
+int arch_register_cpu(int cpu)
+{
+       struct cpu *c = &per_cpu(cpu_devices, cpu);
        int rc;
 
-       c = kzalloc(sizeof(*c), GFP_KERNEL);
-       if (!c)
-               return -ENOMEM;
-       per_cpu(cpu_device, cpu) = c;
-       s = &c->dev;
-       c->hotpluggable = !!cpu;
+       c->hotpluggable = arch_cpu_is_hotpluggable(cpu);
        rc = register_cpu(c, cpu);
        if (rc)
                goto out;
-       rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group);
+       rc = sysfs_create_group(&c->dev.kobj, &cpu_common_attr_group);
        if (rc)
                goto out_cpu;
        rc = topology_cpu_init(c);
@@ -1148,14 +1141,14 @@ static int smp_add_present_cpu(int cpu)
        return 0;
 
 out_topology:
-       sysfs_remove_group(&s->kobj, &cpu_common_attr_group);
+       sysfs_remove_group(&c->dev.kobj, &cpu_common_attr_group);
 out_cpu:
        unregister_cpu(c);
 out:
        return rc;
 }
 
-int __ref smp_rescan_cpus(void)
+int __ref smp_rescan_cpus(bool early)
 {
        struct sclp_core_info *info;
        int nr;
@@ -1164,7 +1157,7 @@ int __ref smp_rescan_cpus(void)
        if (!info)
                return -ENOMEM;
        smp_get_core_info(info, 0);
-       nr = __smp_rescan_cpus(info, false);
+       nr = __smp_rescan_cpus(info, early);
        kfree(info);
        if (nr)
                topology_schedule_update();
@@ -1181,7 +1174,7 @@ static ssize_t __ref rescan_store(struct device *dev,
        rc = lock_device_hotplug_sysfs();
        if (rc)
                return rc;
-       rc = smp_rescan_cpus();
+       rc = smp_rescan_cpus(false);
        unlock_device_hotplug();
        return rc ? rc : count;
 }
@@ -1190,7 +1183,7 @@ static DEVICE_ATTR_WO(rescan);
 static int __init s390_smp_init(void)
 {
        struct device *dev_root;
-       int cpu, rc = 0;
+       int rc;
 
        dev_root = bus_get_dev_root(&cpu_subsys);
        if (dev_root) {
@@ -1199,17 +1192,9 @@ static int __init s390_smp_init(void)
                if (rc)
                        return rc;
        }
-
-       for_each_present_cpu(cpu) {
-               rc = smp_add_present_cpu(cpu);
-               if (rc)
-                       goto out;
-       }
-
        rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "s390/smp:online",
                               smp_cpu_online, smp_cpu_pre_down);
        rc = rc <= 0 ? rc : 0;
-out:
        return rc;
 }
 subsys_initcall(s390_smp_init);
index 10383e936461707c838aa8c61c4bd37430480dfd..f56ea9b60e08e817652a9b7d19d420e9977c6552 100644 (file)
@@ -60,7 +60,7 @@ static void sclp_cpu_capability_notify(struct work_struct *work)
 static void __ref sclp_cpu_change_notify(struct work_struct *work)
 {
        lock_device_hotplug();
-       smp_rescan_cpus();
+       smp_rescan_cpus(false);
        unlock_device_hotplug();
 }