diff options
author | Mete Durlu <meted@linux.ibm.com> | 2024-08-12 13:39:37 +0200 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2024-08-29 22:56:35 +0200 |
commit | b9271a533433dd4049723d4668418709e1927e12 (patch) | |
tree | 4660459f8943dccb96a61b5055b6b93fe1c5a3ff /arch/s390 | |
parent | 1e5aa12d470b1af613fca89a3069529fa9c92cfb (diff) |
s390/hiperdispatch: Add hiperdispatch sysctl interface
Expose hiperdispatch controls via sysctl. The user can now toggle
hiperdispatch via assigning 0 or 1 to s390.hiperdispatch attribute.
When hiperdipatch is toggled on, it tries to adjust CPU capacities,
while system is in vertical polarization to gain performance benefits
from different CPU polarizations. Disabling hiperdispatch reverts the
CPU capacities to their default (HIGH_CAPACITY) and stops the dynamic
adjustments.
Introduce a kconfig option HIPERDISPATCH_ON which allows users to
use hiperdispatch by default on vertical polarization. Using the
sysctl attribute s390.hiperdispatch would overwrite this behavior.
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>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/Kconfig | 12 | ||||
-rw-r--r-- | arch/s390/kernel/hiperdispatch.c | 60 |
2 files changed, 72 insertions, 0 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 2ee634bab222..bc2aab60c1c8 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -521,6 +521,18 @@ config SCHED_TOPOLOGY_VERTICAL Use vertical CPU polarization by default if available. The default CPU polarization is horizontal. +config HIPERDISPATCH_ON + def_bool y + bool "Use hiperdispatch on vertical polarization by default" + depends on SCHED_TOPOLOGY + depends on PROC_SYSCTL + help + Hiperdispatch aims to improve the CPU scheduler's decision + making when using vertical polarization by adjusting CPU + capacities dynamically. Set this option to use hiperdispatch + on vertical polarization by default. This can be overwritten + by sysctl's s390.hiperdispatch attribute later on. + source "kernel/Kconfig.hz" config CERT_STORE diff --git a/arch/s390/kernel/hiperdispatch.c b/arch/s390/kernel/hiperdispatch.c index 3ba7a3492924..8ff4adab7402 100644 --- a/arch/s390/kernel/hiperdispatch.c +++ b/arch/s390/kernel/hiperdispatch.c @@ -48,8 +48,10 @@ #include <linux/cpumask.h> #include <linux/kernel_stat.h> #include <linux/ktime.h> +#include <linux/sysctl.h> #include <linux/workqueue.h> #include <asm/hiperdispatch.h> +#include <asm/setup.h> #include <asm/smp.h> #include <asm/topology.h> @@ -69,9 +71,21 @@ static int hd_online_cores; /* Current online CORE count */ static unsigned long hd_previous_steal; /* Previous iteration's CPU steal timer total */ +static int hd_enabled; + static void hd_capacity_work_fn(struct work_struct *work); static DECLARE_DELAYED_WORK(hd_capacity_work, hd_capacity_work_fn); +static int hd_set_hiperdispatch_mode(int enable) +{ + if (!MACHINE_HAS_TOPOLOGY) + enable = 0; + if (hd_enabled == enable) + return 0; + hd_enabled = enable; + return 1; +} + void hd_reset_state(void) { cpumask_clear(&hd_vl_coremask); @@ -131,6 +145,8 @@ void hd_disable_hiperdispatch(void) int hd_enable_hiperdispatch(void) { + if (hd_enabled == 0) + return 0; if (hd_entitled_cores == 0) return 0; if (hd_online_cores <= hd_entitled_cores) @@ -211,3 +227,47 @@ static void hd_capacity_work_fn(struct work_struct *work) mutex_unlock(&smp_cpu_state_mutex); schedule_delayed_work(&hd_capacity_work, HD_DELAY_INTERVAL); } + +static int hiperdispatch_ctl_handler(const struct ctl_table *ctl, int write, + void *buffer, size_t *lenp, loff_t *ppos) +{ + int hiperdispatch; + int rc; + struct ctl_table ctl_entry = { + .procname = ctl->procname, + .data = &hiperdispatch, + .maxlen = sizeof(int), + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }; + + hiperdispatch = hd_enabled; + rc = proc_douintvec_minmax(&ctl_entry, write, buffer, lenp, ppos); + if (rc < 0 || !write) + return rc; + mutex_lock(&smp_cpu_state_mutex); + if (hd_set_hiperdispatch_mode(hiperdispatch)) + topology_schedule_update(); + mutex_unlock(&smp_cpu_state_mutex); + return 0; +} + +static struct ctl_table hiperdispatch_ctl_table[] = { + { + .procname = "hiperdispatch", + .mode = 0644, + .proc_handler = hiperdispatch_ctl_handler, + }, +}; + +static int __init hd_init(void) +{ + if (IS_ENABLED(CONFIG_HIPERDISPATCH_ON)) { + hd_set_hiperdispatch_mode(1); + topology_schedule_update(); + } + if (!register_sysctl("s390", hiperdispatch_ctl_table)) + pr_warn("Failed to register s390.hiperdispatch sysctl attribute\n"); + return 0; +} +late_initcall(hd_init); |