Skip to content

Commit b9271a5

Browse files
NickJackolsonVasily Gorbik
authored andcommitted
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 <[email protected]> Signed-off-by: Mete Durlu <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent 1e5aa12 commit b9271a5

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

arch/s390/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,18 @@ config SCHED_TOPOLOGY_VERTICAL
521521
Use vertical CPU polarization by default if available.
522522
The default CPU polarization is horizontal.
523523

524+
config HIPERDISPATCH_ON
525+
def_bool y
526+
bool "Use hiperdispatch on vertical polarization by default"
527+
depends on SCHED_TOPOLOGY
528+
depends on PROC_SYSCTL
529+
help
530+
Hiperdispatch aims to improve the CPU scheduler's decision
531+
making when using vertical polarization by adjusting CPU
532+
capacities dynamically. Set this option to use hiperdispatch
533+
on vertical polarization by default. This can be overwritten
534+
by sysctl's s390.hiperdispatch attribute later on.
535+
524536
source "kernel/Kconfig.hz"
525537

526538
config CERT_STORE

arch/s390/kernel/hiperdispatch.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@
4848
#include <linux/cpumask.h>
4949
#include <linux/kernel_stat.h>
5050
#include <linux/ktime.h>
51+
#include <linux/sysctl.h>
5152
#include <linux/workqueue.h>
5253
#include <asm/hiperdispatch.h>
54+
#include <asm/setup.h>
5355
#include <asm/smp.h>
5456
#include <asm/topology.h>
5557

@@ -69,9 +71,21 @@ static int hd_online_cores; /* Current online CORE count */
6971

7072
static unsigned long hd_previous_steal; /* Previous iteration's CPU steal timer total */
7173

74+
static int hd_enabled;
75+
7276
static void hd_capacity_work_fn(struct work_struct *work);
7377
static DECLARE_DELAYED_WORK(hd_capacity_work, hd_capacity_work_fn);
7478

79+
static int hd_set_hiperdispatch_mode(int enable)
80+
{
81+
if (!MACHINE_HAS_TOPOLOGY)
82+
enable = 0;
83+
if (hd_enabled == enable)
84+
return 0;
85+
hd_enabled = enable;
86+
return 1;
87+
}
88+
7589
void hd_reset_state(void)
7690
{
7791
cpumask_clear(&hd_vl_coremask);
@@ -131,6 +145,8 @@ void hd_disable_hiperdispatch(void)
131145

132146
int hd_enable_hiperdispatch(void)
133147
{
148+
if (hd_enabled == 0)
149+
return 0;
134150
if (hd_entitled_cores == 0)
135151
return 0;
136152
if (hd_online_cores <= hd_entitled_cores)
@@ -211,3 +227,47 @@ static void hd_capacity_work_fn(struct work_struct *work)
211227
mutex_unlock(&smp_cpu_state_mutex);
212228
schedule_delayed_work(&hd_capacity_work, HD_DELAY_INTERVAL);
213229
}
230+
231+
static int hiperdispatch_ctl_handler(const struct ctl_table *ctl, int write,
232+
void *buffer, size_t *lenp, loff_t *ppos)
233+
{
234+
int hiperdispatch;
235+
int rc;
236+
struct ctl_table ctl_entry = {
237+
.procname = ctl->procname,
238+
.data = &hiperdispatch,
239+
.maxlen = sizeof(int),
240+
.extra1 = SYSCTL_ZERO,
241+
.extra2 = SYSCTL_ONE,
242+
};
243+
244+
hiperdispatch = hd_enabled;
245+
rc = proc_douintvec_minmax(&ctl_entry, write, buffer, lenp, ppos);
246+
if (rc < 0 || !write)
247+
return rc;
248+
mutex_lock(&smp_cpu_state_mutex);
249+
if (hd_set_hiperdispatch_mode(hiperdispatch))
250+
topology_schedule_update();
251+
mutex_unlock(&smp_cpu_state_mutex);
252+
return 0;
253+
}
254+
255+
static struct ctl_table hiperdispatch_ctl_table[] = {
256+
{
257+
.procname = "hiperdispatch",
258+
.mode = 0644,
259+
.proc_handler = hiperdispatch_ctl_handler,
260+
},
261+
};
262+
263+
static int __init hd_init(void)
264+
{
265+
if (IS_ENABLED(CONFIG_HIPERDISPATCH_ON)) {
266+
hd_set_hiperdispatch_mode(1);
267+
topology_schedule_update();
268+
}
269+
if (!register_sysctl("s390", hiperdispatch_ctl_table))
270+
pr_warn("Failed to register s390.hiperdispatch sysctl attribute\n");
271+
return 0;
272+
}
273+
late_initcall(hd_init);

0 commit comments

Comments
 (0)