]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/smp: Add cpu capacities
authorMete Durlu <meted@linux.ibm.com>
Mon, 12 Aug 2024 11:39:33 +0000 (13:39 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Thu, 29 Aug 2024 20:56:35 +0000 (22:56 +0200)
Linux scheduler allows architectures to assign capacity values to
individual CPUs. This hints scheduler the performance difference between
CPUs and allows more efficient task distribution them. Implement
helper methods to set and get CPU capacities for s390. This is
particularly helpful in vertical polarization configurations of LPARs.
On vertical polarization an LPARs CPUs can get different polarization
values depending on the CEC configuration. CPUs with different
polarization values can perform different from each other, using CPU
capacities this can be reflected to linux scheduler.

Acked-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/include/asm/processor.h
arch/s390/include/asm/smp.h
arch/s390/include/asm/topology.h
arch/s390/kernel/smp.c

index 5ecd442535b9ed260a889361a63960277718d69a..9a5236acc0a86053b199cace2ed54f1c367f540f 100644 (file)
@@ -44,6 +44,7 @@ struct pcpu {
        unsigned long ec_mask;          /* bit mask for ec_xxx functions */
        unsigned long ec_clk;           /* sigp timestamp for ec_xxx */
        unsigned long flags;            /* per CPU flags */
+       unsigned long capacity;         /* cpu capacity for scheduler */
        signed char state;              /* physical cpu state */
        signed char polarization;       /* physical polarization */
        u16 address;                    /* physical cpu address */
index cd835f4fb11a1dafcab776bef676542765c799c9..7feca96c48c6a2e6db8c92a9496ad785cba49348 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/processor.h>
 
 #define raw_smp_processor_id() (get_lowcore()->cpu_nr)
+#define arch_scale_cpu_capacity smp_cpu_get_capacity
 
 extern struct mutex smp_cpu_state_mutex;
 extern unsigned int smp_cpu_mt_shift;
@@ -34,6 +35,9 @@ extern void smp_save_dump_secondary_cpus(void);
 extern void smp_yield_cpu(int cpu);
 extern void smp_cpu_set_polarization(int cpu, int val);
 extern int smp_cpu_get_polarization(int cpu);
+extern void smp_cpu_set_capacity(int cpu, unsigned long val);
+extern void smp_set_core_capacity(int cpu, unsigned long val);
+extern unsigned long smp_cpu_get_capacity(int cpu);
 extern int smp_cpu_get_cpu_address(int cpu);
 extern void smp_fill_possible_mask(void);
 extern void smp_detect_cpus(void);
index 3a0ac0c7a9a39b030e316f7074e38793146b93ed..cef06bffad8041a444ab8ff4b4a191028d951448 100644 (file)
@@ -67,6 +67,9 @@ static inline void topology_expect_change(void) { }
 #define POLARIZATION_VM                (2)
 #define POLARIZATION_VH                (3)
 
+#define CPU_CAPACITY_HIGH      SCHED_CAPACITY_SCALE
+#define CPU_CAPACITY_LOW       (SCHED_CAPACITY_SCALE >> 3)
+
 #define SD_BOOK_INIT   SD_CPU_INIT
 
 #ifdef CONFIG_NUMA
index fbba37ec53cf7d507c4890c21a02b93a1ad280d5..4df56fdb248807587dcd56634d84d3fbdfaeb50c 100644 (file)
@@ -671,6 +671,25 @@ int smp_cpu_get_polarization(int cpu)
        return per_cpu(pcpu_devices, cpu).polarization;
 }
 
+void smp_cpu_set_capacity(int cpu, unsigned long val)
+{
+       per_cpu(pcpu_devices, cpu).capacity = val;
+}
+
+unsigned long smp_cpu_get_capacity(int cpu)
+{
+       return per_cpu(pcpu_devices, cpu).capacity;
+}
+
+void smp_set_core_capacity(int cpu, unsigned long val)
+{
+       int i;
+
+       cpu = smp_get_base_cpu(cpu);
+       for (i = cpu; (i <= cpu + smp_cpu_mtid) && (i < nr_cpu_ids); i++)
+               smp_cpu_set_capacity(i, val);
+}
+
 int smp_cpu_get_cpu_address(int cpu)
 {
        return per_cpu(pcpu_devices, cpu).address;
@@ -719,6 +738,7 @@ static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail,
                else
                        pcpu->state = CPU_STATE_STANDBY;
                smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
+               smp_cpu_set_capacity(cpu, CPU_CAPACITY_HIGH);
                set_cpu_present(cpu, true);
                if (!early && arch_register_cpu(cpu))
                        set_cpu_present(cpu, false);
@@ -961,6 +981,7 @@ void __init smp_prepare_boot_cpu(void)
        ipl_pcpu->state = CPU_STATE_CONFIGURED;
        lc->pcpu = (unsigned long)ipl_pcpu;
        smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
+       smp_cpu_set_capacity(0, CPU_CAPACITY_HIGH);
 }
 
 void __init smp_setup_processor_id(void)