[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20211027204319.22697-3-paul.gortmaker@windriver.com>
Date: Wed, 27 Oct 2021 16:43:19 -0400
From: Paul Gortmaker <paul.gortmaker@...driver.com>
To: <linux-kernel@...r.kernel.org>
CC: Paul Gortmaker <paul.gortmaker@...driver.com>,
Ingo Molnar <mingo@...hat.com>,
Steven Rostedt <rostedt@...dmis.org>,
Thomas Gleixner <tglx@...utronix.de>,
Peter Zijlstra <peterz@...radead.org>,
Josh Triplett <josh@...htriplett.org>,
"Paul E . McKenney" <paulmck@...nel.org>,
"Frederic Weisbecker" <frederic@...nel.org>,
Valentin Schneider <valentin.schneider@....com>
Subject: [PATCH 2/2] cpuset: add binding to CPU isolation
The idea is to put one or a group of cores into a set and then use
that set to control the core's isolation setting.
Currently the isolation only toggles RCU nocb, and note that a
limitation exists where you can only RCU toggle if you use a boot
arg to enable nocb offload at boot initially. So the 1st offload
request of the subset in the cpuset are no-ops.
An example probably describes things the best:
root@...kbox:/sys/fs/cgroup/cpuset# cat /proc/cmdline
BOOT_IMAGE=/boot/bzImage rcu_nocbs=1-11 root=/dev/sda3 console=ttyS0,115200 ro
root@...kbox:/sys/fs/cgroup/cpuset# dmesg|grep Offload
[ 0.154015] rcu: Offload RCU callbacks from CPUs: 1-11.
root@...kbox:/sys/fs/cgroup/cpuset# mkdir cores4-6
root@...kbox:/sys/fs/cgroup/cpuset# cd cores4-6/
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6# dmesg -c > /dev/null
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6# echo 4-6 > cpuset.cpus
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6# dmesg
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6# echo 1 > cpuset.cpu_isolation
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6# dmesg
[ 1021.217641] Isolating core 4
[ 1021.217650] Isolating core 5
[ 1021.217651] Isolating core 6
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6# dmesg -c > /dev/null
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6# echo 0 > cpuset.cpu_isolation
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6# dmesg
[ 1050.589700] Deisolating core 4
[ 1050.589778] rcu: De-offloading 4
[ 1050.590001] Deisolating core 5
[ 1050.590065] rcu: De-offloading 5
[ 1050.590284] Deisolating core 6
[ 1050.590366] rcu: De-offloading 6
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6# dmesg -c > /dev/null
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6# echo 1 > cpuset.cpu_isolation
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6# dmesg
[ 1071.584802] Isolating core 4
[ 1071.584886] rcu: Offloading 4
[ 1071.585130] Isolating core 5
[ 1071.585203] rcu: Offloading 5
[ 1071.585448] Isolating core 6
[ 1071.585459] rcu: Offloading 6
root@...kbox:/sys/fs/cgroup/cpuset/cores4-6#
Cc: Ingo Molnar <mingo@...hat.com>
Cc: Steven Rostedt <rostedt@...dmis.org>
Cc: Thomas Gleixner <tglx@...utronix.de>
Cc: Peter Zijlstra <peterz@...radead.org>
Cc: Josh Triplett <josh@...htriplett.org>
Cc: Paul E. McKenney <paulmck@...nel.org>
Cc: Frederic Weisbecker <frederic@...nel.org>
Cc: Valentin Schneider <valentin.schneider@....com>
[PG: RFC code - not for merge]
Signed-off-by: Paul Gortmaker <paul.gortmaker@...driver.com>
---
kernel/cgroup/cpuset.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index adb5190c4429..4420bffcc232 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -209,6 +209,7 @@ static inline struct cpuset *parent_cs(struct cpuset *cs)
typedef enum {
CS_ONLINE,
CS_CPU_EXCLUSIVE,
+ CS_CPU_ISOLATED,
CS_MEM_EXCLUSIVE,
CS_MEM_HARDWALL,
CS_MEMORY_MIGRATE,
@@ -228,6 +229,11 @@ static inline int is_cpu_exclusive(const struct cpuset *cs)
return test_bit(CS_CPU_EXCLUSIVE, &cs->flags);
}
+static inline int is_cpu_isolated(const struct cpuset *cs)
+{
+ return test_bit(CS_CPU_ISOLATED, &cs->flags);
+}
+
static inline int is_mem_exclusive(const struct cpuset *cs)
{
return test_bit(CS_MEM_EXCLUSIVE, &cs->flags);
@@ -1866,6 +1872,23 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val)
return 0;
}
+/**
+ * update_isol_state - update isolated state for allowed cores
+ * @cs: the cpuset in which each core might need to be changed
+ *
+ */
+static void update_isol_state(struct cpuset *cs)
+{
+ struct cpumask *mask = cs->cpus_allowed;
+ int cpu, isolate = is_cpu_isolated(cs);
+
+ for_each_cpu(cpu, mask)
+ if (isolate)
+ isolate_cpu(cpu);
+ else
+ deisolate_cpu(cpu);
+}
+
/**
* update_tasks_flags - update the spread flags of tasks in the cpuset.
* @cs: the cpuset in which each task's spread flags needs to be changed
@@ -1900,6 +1923,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
struct cpuset *trialcs;
int balance_flag_changed;
int spread_flag_changed;
+ int isol_flag_changed;
int err;
trialcs = alloc_trial_cpuset(cs);
@@ -1921,6 +1945,8 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
spread_flag_changed = ((is_spread_slab(cs) != is_spread_slab(trialcs))
|| (is_spread_page(cs) != is_spread_page(trialcs)));
+ isol_flag_changed = (is_cpu_isolated(cs) != is_cpu_isolated(trialcs));
+
spin_lock_irq(&callback_lock);
cs->flags = trialcs->flags;
spin_unlock_irq(&callback_lock);
@@ -1930,6 +1956,9 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
if (spread_flag_changed)
update_tasks_flags(cs);
+
+ if (isol_flag_changed)
+ update_isol_state(cs);
out:
free_cpuset(trialcs);
return err;
@@ -2264,6 +2293,7 @@ typedef enum {
FILE_EFFECTIVE_MEMLIST,
FILE_SUBPARTS_CPULIST,
FILE_CPU_EXCLUSIVE,
+ FILE_CPU_ISOLATED,
FILE_MEM_EXCLUSIVE,
FILE_MEM_HARDWALL,
FILE_SCHED_LOAD_BALANCE,
@@ -2293,6 +2323,9 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft,
case FILE_CPU_EXCLUSIVE:
retval = update_flag(CS_CPU_EXCLUSIVE, cs, val);
break;
+ case FILE_CPU_ISOLATED:
+ retval = update_flag(CS_CPU_ISOLATED, cs, val);
+ break;
case FILE_MEM_EXCLUSIVE:
retval = update_flag(CS_MEM_EXCLUSIVE, cs, val);
break;
@@ -2465,6 +2498,8 @@ static u64 cpuset_read_u64(struct cgroup_subsys_state *css, struct cftype *cft)
switch (type) {
case FILE_CPU_EXCLUSIVE:
return is_cpu_exclusive(cs);
+ case FILE_CPU_ISOLATED:
+ return is_cpu_isolated(cs);
case FILE_MEM_EXCLUSIVE:
return is_mem_exclusive(cs);
case FILE_MEM_HARDWALL:
@@ -2595,6 +2630,13 @@ static struct cftype legacy_files[] = {
.private = FILE_CPU_EXCLUSIVE,
},
+ {
+ .name = "cpu_isolation",
+ .read_u64 = cpuset_read_u64,
+ .write_u64 = cpuset_write_u64,
+ .private = FILE_CPU_ISOLATED,
+ },
+
{
.name = "mem_exclusive",
.read_u64 = cpuset_read_u64,
--
2.15.0
Powered by blists - more mailing lists