Commit b9271a53 authored by Mete Durlu's avatar Mete Durlu Committed by Vasily Gorbik

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: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarMete Durlu <meted@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 1e5aa12d
......@@ -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
......
......@@ -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);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment