[PATCH 2/2][RFC] sched/debug: Make sd->flags sysctl writable again
From: Chen Yu
Date: Mon Jul 06 2020 - 15:35:51 EST
The flags of sched domain in sysctl was limited to read-only in a
recent change. However this might bring inconvenience to some performance
tuning/function test which are sensitive to load balance. Since
the user might want to evaluate the impact of different combination
of sched domain flags on the workloads.
Per Commit 9818427c6270 ("sched/debug: Make sd->flags sysctl read-only"),
we can make the flags writable if we update the cached pointers after
the flag of sched domain has been modified.
Leverage update_domain_cpu() to update corresponding cached pointer of that
CPU once the flags has been changed.
Signed-off-by: Chen Yu <yu.c.chen@xxxxxxxxx>
---
kernel/sched/debug.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 36c54265bb2b..bfeaf547d4af 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -227,6 +227,8 @@ static void sd_free_ctl_entry(struct ctl_table **tablep)
sd_free_ctl_entry(&entry->child);
if (entry->proc_handler == NULL)
kfree(entry->procname);
+ if (entry->extra1)
+ kfree(entry->extra1);
}
kfree(*tablep);
@@ -245,20 +247,42 @@ set_table_entry(struct ctl_table *entry,
entry->proc_handler = proc_handler;
}
+static int sysctl_sd_flags_handler(struct ctl_table *table, int write, void *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ int ret;
+
+ ret = proc_dointvec(table, write, buffer, lenp, ppos);
+ if (!ret && write)
+ update_domain_cpu(*(int *)(table->extra1));
+
+ return ret;
+}
+
static struct ctl_table *
-sd_alloc_ctl_domain_table(struct sched_domain *sd)
+sd_alloc_ctl_domain_table(struct sched_domain *sd, int cpu)
{
struct ctl_table *table = sd_alloc_ctl_entry(9);
+ int *cpu_param;
if (table == NULL)
return NULL;
+ /* Pass the CPU index to the handler. */
+ cpu_param = kmalloc(sizeof(int), GFP_KERNEL);
+ if (!cpu_param) {
+ kfree(table);
+ return NULL;
+ }
+ *cpu_param = cpu;
+
set_table_entry(&table[0], "min_interval", &sd->min_interval, sizeof(long), 0644, proc_doulongvec_minmax);
set_table_entry(&table[1], "max_interval", &sd->max_interval, sizeof(long), 0644, proc_doulongvec_minmax);
set_table_entry(&table[2], "busy_factor", &sd->busy_factor, sizeof(int), 0644, proc_dointvec_minmax);
set_table_entry(&table[3], "imbalance_pct", &sd->imbalance_pct, sizeof(int), 0644, proc_dointvec_minmax);
set_table_entry(&table[4], "cache_nice_tries", &sd->cache_nice_tries, sizeof(int), 0644, proc_dointvec_minmax);
- set_table_entry(&table[5], "flags", &sd->flags, sizeof(int), 0444, proc_dointvec_minmax);
+ set_table_entry(&table[5], "flags", &sd->flags, sizeof(int), 0644, sysctl_sd_flags_handler);
+ table[5].extra1 = (void *)cpu_param;
set_table_entry(&table[6], "max_newidle_lb_cost", &sd->max_newidle_lb_cost, sizeof(long), 0644, proc_doulongvec_minmax);
set_table_entry(&table[7], "name", sd->name, CORENAME_MAX_SIZE, 0444, proc_dostring);
/* &table[8] is terminator */
@@ -284,7 +308,7 @@ static struct ctl_table *sd_alloc_ctl_cpu_table(int cpu)
snprintf(buf, 32, "domain%d", i);
entry->procname = kstrdup(buf, GFP_KERNEL);
entry->mode = 0555;
- entry->child = sd_alloc_ctl_domain_table(sd);
+ entry->child = sd_alloc_ctl_domain_table(sd, cpu);
entry++;
i++;
}
--
2.17.1