From: Mete Durlu Date: Mon, 12 Aug 2024 11:39:37 +0000 (+0200) Subject: s390/hiperdispatch: Add hiperdispatch sysctl interface X-Git-Tag: v6.12-rc1~113^2~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b9271a533433dd4049723d4668418709e1927e12;p=thirdparty%2Fkernel%2Flinux.git 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 Signed-off-by: Mete Durlu Signed-off-by: Vasily Gorbik --- diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 2ee634bab222d..bc2aab60c1c8f 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 3ba7a3492924b..8ff4adab7402a 100644 --- a/arch/s390/kernel/hiperdispatch.c +++ b/arch/s390/kernel/hiperdispatch.c @@ -48,8 +48,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -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);