#include <linux/sched.h>
#include <linux/cpumask.h>
#include <linux/cpuset.h>
#include <linux/debugfs.h>
#include <linux/mutex.h>
#include <linux/sysctl.h>
#include <linux/nodemask.h>
static DEFINE_MUTEX(itmt_update_mutex);
DEFINE_PER_CPU_READ_MOSTLY(int, sched_core_priority);
static bool __read_mostly sched_itmt_capable;
bool __read_mostly sysctl_sched_itmt_enabled;
static ssize_t sched_itmt_enabled_write(struct file *filp,
const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
ssize_t result;
bool orig;
guard(mutex)(&itmt_update_mutex);
orig = sysctl_sched_itmt_enabled;
result = debugfs_write_file_bool(filp, ubuf, cnt, ppos);
if (sysctl_sched_itmt_enabled != orig) {
x86_topology_update = true;
rebuild_sched_domains();
}
return result;
}
static int sched_core_priority_show(struct seq_file *s, void *unused)
{
int cpu;
seq_puts(s, "CPU #\tPriority\n");
for_each_possible_cpu(cpu)
seq_printf(s, "%d\t%d\n", cpu, arch_asym_cpu_priority(cpu));
return 0;
}
DEFINE_SHOW_ATTRIBUTE(sched_core_priority);
static const struct file_operations dfs_sched_itmt_fops = {
.read = debugfs_read_file_bool,
.write = sched_itmt_enabled_write,
.open = simple_open,
.llseek = default_llseek,
};
static struct dentry *dfs_sched_itmt;
static struct dentry *dfs_sched_core_prio;
int sched_set_itmt_support(void)
{
guard(mutex)(&itmt_update_mutex);
if (sched_itmt_capable)
return 0;
dfs_sched_itmt = debugfs_create_file_unsafe("sched_itmt_enabled",
0644,
arch_debugfs_dir,
&sysctl_sched_itmt_enabled,
&dfs_sched_itmt_fops);
if (IS_ERR_OR_NULL(dfs_sched_itmt)) {
dfs_sched_itmt = NULL;
return -ENOMEM;
}
dfs_sched_core_prio = debugfs_create_file("sched_core_priority", 0644,
arch_debugfs_dir, NULL,
&sched_core_priority_fops);
if (IS_ERR_OR_NULL(dfs_sched_core_prio)) {
dfs_sched_core_prio = NULL;
return -ENOMEM;
}
sched_itmt_capable = true;
sysctl_sched_itmt_enabled = 1;
x86_topology_update = true;
rebuild_sched_domains();
return 0;
}
void sched_clear_itmt_support(void)
{
guard(mutex)(&itmt_update_mutex);
if (!sched_itmt_capable)
return;
sched_itmt_capable = false;
debugfs_remove(dfs_sched_itmt);
dfs_sched_itmt = NULL;
debugfs_remove(dfs_sched_core_prio);
dfs_sched_core_prio = NULL;
if (sysctl_sched_itmt_enabled) {
sysctl_sched_itmt_enabled = 0;
x86_topology_update = true;
rebuild_sched_domains();
}
}
int arch_asym_cpu_priority(int cpu)
{
return per_cpu(sched_core_priority, cpu);
}
void sched_set_itmt_core_prio(int prio, int cpu)
{
per_cpu(sched_core_priority, cpu) = prio;
}