History

cgroup/cpuset: Expand the scope of cpuset_can_attach_check()

Expand the scope of cpuset_can_attach_check() by including the setting of setsched flag inside cpuset_can_attach_check() with the new @oldcs and @psetsched argument. As cpuset_can_attach_check() is also called from cpuset_can_fork(), set the new arguments to NULL from that caller.

Waiman Long committed 4 months ago

Commit 74eda6e1 parent e165f241 file · +30 −22Browse files

Unified · Split

kernel/cgroup/cpuset.c+30−22
@@ -3022,12 +3022,39 @@ out: · 3021 unmodified lines
30223022 * For v1, cpus_allowed and mems_allowed can't be empty.
30233023 * For v2, effective_cpus can't be empty.
30243024 * Note that in v1, effective_cpus = cpus_allowed.
3025+ *
3026+ * Also set the boolean flag passed in by @psetsched depending on if
3027+ * security_task_setscheduler() call is needed and @oldcs is not NULL.
30253028 */
3026−static int cpuset_can_attach_check(struct cpuset *cs)
3029+static int cpuset_can_attach_check(struct cpuset *cs, struct cpuset *oldcs,
3030+ bool *psetsched)
30273031 {
30283032 if (cpumask_empty(cs->effective_cpus) ||
30293033 (!is_in_v2_mode() && nodes_empty(cs->mems_allowed)))
30303034 return -ENOSPC;
3035+
3036+ if (!oldcs)
3037+ return 0;
3038+
3039+ /*
3040+ * Skip rights over task setsched check in v2 when nothing changes,
3041+ * migration permission derives from hierarchy ownership in
3042+ * cgroup_procs_write_permission()).
3043+ */
3044+ *psetsched = !cpuset_v2() ||
3045+ !cpumask_equal(cs->effective_cpus, oldcs->effective_cpus) ||
3046+ !nodes_equal(cs->effective_mems, oldcs->effective_mems);
3047+
3048+ /*
3049+ * A v1 cpuset with tasks will have no CPU left only when CPU hotplug
3050+ * brings the last online CPU offline as users are not allowed to empty
3051+ * cpuset.cpus when there are active tasks inside. When that happens,
3052+ * we should allow tasks to migrate out without security check to make
3053+ * sure they will be able to run after migration.
3054+ */
3055+ if (!is_in_v2_mode() && cpumask_empty(oldcs->effective_cpus))
3056+ *psetsched = false;
3057+
30313058 return 0;
30323059 }
30333060
@@ -3074,29 +3101,10 @@ static int cpuset_can_attach(struct cgroup_taskset *tset) · 40 unmodified lines
30743101 mutex_lock(&cpuset_mutex);
30753102
30763103 /* Check to see if task is allowed in the cpuset */
3077− ret = cpuset_can_attach_check(cs);
3104+ ret = cpuset_can_attach_check(cs, oldcs, &setsched_check);
30783105 if (ret)
30793106 goto out_unlock;
30803107
3081− /*
3082− * Skip rights over task setsched check in v2 when nothing changes,
3083− * migration permission derives from hierarchy ownership in
3084− * cgroup_procs_write_permission()).
3085− */
3086− setsched_check = !cpuset_v2() ||
3087− !cpumask_equal(cs->effective_cpus, oldcs->effective_cpus) ||
3088− !nodes_equal(cs->effective_mems, oldcs->effective_mems);
3089−
3090− /*
3091− * A v1 cpuset with tasks will have no CPU left only when CPU hotplug
3092− * brings the last online CPU offline as users are not allowed to empty
3093− * cpuset.cpus when there are active tasks inside. When that happens,
3094− * we should allow tasks to migrate out without security check to make
3095− * sure they will be able to run after migration.
3096− */
3097− if (!is_in_v2_mode() && cpumask_empty(oldcs->effective_cpus))
3098− setsched_check = false;
3099−
31003108 cgroup_taskset_for_each(task, css, tset) {
31013109 ret = task_can_attach(task);
31023110 if (ret)
@@ -3639,7 +3647,7 @@ static int cpuset_can_fork(struct task_struct *task, struct css_set *cset) · 536 unmodified lines
36393647 mutex_lock(&cpuset_mutex);
36403648
36413649 /* Check to see if task is allowed in the cpuset */
3642− ret = cpuset_can_attach_check(cs);
3650+ ret = cpuset_can_attach_check(cs, NULL, NULL);
36433651 if (ret)
36443652 goto out_unlock;
36453653