diff --git a/patches.kernel.org/6.2.12-119-cgroup-cpuset-Add-cpuset_can_fork-and-cpuset_c.patch b/patches.kernel.org/6.2.12-119-cgroup-cpuset-Add-cpuset_can_fork-and-cpuset_c.patch new file mode 100644 index 0000000..b13e850 --- /dev/null +++ b/patches.kernel.org/6.2.12-119-cgroup-cpuset-Add-cpuset_can_fork-and-cpuset_c.patch @@ -0,0 +1,178 @@ +From: Waiman Long +Date: Tue, 11 Apr 2023 09:35:59 -0400 +Subject: [PATCH] cgroup/cpuset: Add cpuset_can_fork() and cpuset_cancel_fork() + methods +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +References: bsc#1012628 +Patch-mainline: 6.2.12 +Git-commit: eee87853794187f6adbe19533ed79c8b44b36a91 + +commit eee87853794187f6adbe19533ed79c8b44b36a91 upstream. + +In the case of CLONE_INTO_CGROUP, not all cpusets are ready to accept +new tasks. It is too late to check that in cpuset_fork(). So we need +to add the cpuset_can_fork() and cpuset_cancel_fork() methods to +pre-check it before we can allow attachment to a different cpuset. + +We also need to set the attach_in_progress flag to alert other code +that a new task is going to be added to the cpuset. + +Fixes: ef2c41cf38a7 ("clone3: allow spawning processes into cgroups") +Suggested-by: Michal Koutný +Signed-off-by: Waiman Long +Cc: stable@vger.kernel.org # v5.7+ +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Jiri Slaby +--- + kernel/cgroup/cpuset.c | 97 +++++++++++++++++++++++++++++++++++++----- + 1 file changed, 86 insertions(+), 11 deletions(-) + +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index 9714fd65..e89af77e 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -2453,6 +2453,20 @@ static int fmeter_getrate(struct fmeter *fmp) + + static struct cpuset *cpuset_attach_old_cs; + ++/* ++ * Check to see if a cpuset can accept a new task ++ * For v1, cpus_allowed and mems_allowed can't be empty. ++ * For v2, effective_cpus can't be empty. ++ * Note that in v1, effective_cpus = cpus_allowed. ++ */ ++static int cpuset_can_attach_check(struct cpuset *cs) ++{ ++ if (cpumask_empty(cs->effective_cpus) || ++ (!is_in_v2_mode() && nodes_empty(cs->mems_allowed))) ++ return -ENOSPC; ++ return 0; ++} ++ + /* Called by cgroups to determine if a cpuset is usable; cpuset_rwsem held */ + static int cpuset_can_attach(struct cgroup_taskset *tset) + { +@@ -2467,16 +2481,9 @@ static int cpuset_can_attach(struct cgroup_taskset *tset) + + percpu_down_write(&cpuset_rwsem); + +- /* allow moving tasks into an empty cpuset if on default hierarchy */ +- ret = -ENOSPC; +- if (!is_in_v2_mode() && +- (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))) +- goto out_unlock; +- +- /* +- * Task cannot be moved to a cpuset with empty effective cpus. +- */ +- if (cpumask_empty(cs->effective_cpus)) ++ /* Check to see if task is allowed in the cpuset */ ++ ret = cpuset_can_attach_check(cs); ++ if (ret) + goto out_unlock; + + cgroup_taskset_for_each(task, css, tset) { +@@ -2493,7 +2500,6 @@ static int cpuset_can_attach(struct cgroup_taskset *tset) + * changes which zero cpus/mems_allowed. + */ + cs->attach_in_progress++; +- ret = 0; + out_unlock: + percpu_up_write(&cpuset_rwsem); + return ret; +@@ -3264,6 +3270,68 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css) + percpu_up_write(&cpuset_rwsem); + } + ++/* ++ * In case the child is cloned into a cpuset different from its parent, ++ * additional checks are done to see if the move is allowed. ++ */ ++static int cpuset_can_fork(struct task_struct *task, struct css_set *cset) ++{ ++ struct cpuset *cs = css_cs(cset->subsys[cpuset_cgrp_id]); ++ bool same_cs; ++ int ret; ++ ++ rcu_read_lock(); ++ same_cs = (cs == task_cs(current)); ++ rcu_read_unlock(); ++ ++ if (same_cs) ++ return 0; ++ ++ lockdep_assert_held(&cgroup_mutex); ++ percpu_down_write(&cpuset_rwsem); ++ ++ /* Check to see if task is allowed in the cpuset */ ++ ret = cpuset_can_attach_check(cs); ++ if (ret) ++ goto out_unlock; ++ ++ ret = task_can_attach(task, cs->effective_cpus); ++ if (ret) ++ goto out_unlock; ++ ++ ret = security_task_setscheduler(task); ++ if (ret) ++ goto out_unlock; ++ ++ /* ++ * Mark attach is in progress. This makes validate_change() fail ++ * changes which zero cpus/mems_allowed. ++ */ ++ cs->attach_in_progress++; ++out_unlock: ++ percpu_up_write(&cpuset_rwsem); ++ return ret; ++} ++ ++static void cpuset_cancel_fork(struct task_struct *task, struct css_set *cset) ++{ ++ struct cpuset *cs = css_cs(cset->subsys[cpuset_cgrp_id]); ++ bool same_cs; ++ ++ rcu_read_lock(); ++ same_cs = (cs == task_cs(current)); ++ rcu_read_unlock(); ++ ++ if (same_cs) ++ return; ++ ++ percpu_down_write(&cpuset_rwsem); ++ cs->attach_in_progress--; ++ if (!cs->attach_in_progress) ++ wake_up(&cpuset_attach_wq); ++ percpu_up_write(&cpuset_rwsem); ++} ++ + /* + * Make sure the new task conform to the current state of its parent, + * which could have been changed by cpuset just after it inherits the +@@ -3292,6 +3360,11 @@ static void cpuset_fork(struct task_struct *task) + percpu_down_write(&cpuset_rwsem); + guarantee_online_mems(cs, &cpuset_attach_nodemask_to); + cpuset_attach_task(cs, task); ++ ++ cs->attach_in_progress--; ++ if (!cs->attach_in_progress) ++ wake_up(&cpuset_attach_wq); ++ + percpu_up_write(&cpuset_rwsem); + } + +@@ -3305,6 +3378,8 @@ struct cgroup_subsys cpuset_cgrp_subsys = { + .attach = cpuset_attach, + .post_attach = cpuset_post_attach, + .bind = cpuset_bind, ++ .can_fork = cpuset_can_fork, ++ .cancel_fork = cpuset_cancel_fork, + .fork = cpuset_fork, + .legacy_cftypes = legacy_files, + .dfl_cftypes = dfl_files, +-- +2.35.3 + diff --git a/series.conf b/series.conf index 3657c13..0c0a120 100644 --- a/series.conf +++ b/series.conf @@ -2346,6 +2346,7 @@ patches.kernel.org/6.2.12-116-cgroup-cpuset-Fix-partition-root-s-cpuset.cpus.patch patches.kernel.org/6.2.12-117-cgroup-cpuset-Wake-up-cpuset_attach_wq-tasks-i.patch patches.kernel.org/6.2.12-118-cgroup-cpuset-Make-cpuset_fork-handle-CLONE_IN.patch + patches.kernel.org/6.2.12-119-cgroup-cpuset-Add-cpuset_can_fork-and-cpuset_c.patch ######################################################## # Build fixes that apply to the vanilla kernel too.