Skip to content

Commit 7a2127e

Browse files
willdeaconhtejun
authored andcommitted
cpuset: Call set_cpus_allowed_ptr() with appropriate mask for task
set_cpus_allowed_ptr() will fail with -EINVAL if the requested affinity mask is not a subset of the task_cpu_possible_mask() for the task being updated. Consequently, on a heterogeneous system with cpusets spanning the different CPU types, updates to the cgroup hierarchy can silently fail to update task affinities when the effective affinity mask for the cpuset is expanded. For example, consider an arm64 system with 4 CPUs, where CPUs 2-3 are the only cores capable of executing 32-bit tasks. Attaching a 32-bit task to a cpuset containing CPUs 0-2 will correctly affine the task to CPU 2. Extending the cpuset to CPUs 0-3, however, will fail to extend the affinity mask of the 32-bit task because update_tasks_cpumask() will pass the full 0-3 mask to set_cpus_allowed_ptr(). Extend update_tasks_cpumask() to take a temporary 'cpumask' paramater and use it to mask the 'effective_cpus' mask with the possible mask for each task being updated. Fixes: 431c69f ("cpuset: Honour task_cpu_possible_mask() in guarantee_online_cpus()") Signed-off-by: Will Deacon <[email protected]> Acked-by: Waiman Long <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent 3fb906e commit 7a2127e

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

kernel/cgroup/cpuset.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,12 +1205,13 @@ void rebuild_sched_domains(void)
12051205
/**
12061206
* update_tasks_cpumask - Update the cpumasks of tasks in the cpuset.
12071207
* @cs: the cpuset in which each task's cpus_allowed mask needs to be changed
1208+
* @new_cpus: the temp variable for the new effective_cpus mask
12081209
*
12091210
* Iterate through each task of @cs updating its cpus_allowed to the
12101211
* effective cpuset's. As this function is called with cpuset_rwsem held,
12111212
* cpuset membership stays stable.
12121213
*/
1213-
static void update_tasks_cpumask(struct cpuset *cs)
1214+
static void update_tasks_cpumask(struct cpuset *cs, struct cpumask *new_cpus)
12141215
{
12151216
struct css_task_iter it;
12161217
struct task_struct *task;
@@ -1224,7 +1225,10 @@ static void update_tasks_cpumask(struct cpuset *cs)
12241225
if (top_cs && (task->flags & PF_KTHREAD) &&
12251226
kthread_is_per_cpu(task))
12261227
continue;
1227-
set_cpus_allowed_ptr(task, cs->effective_cpus);
1228+
1229+
cpumask_and(new_cpus, cs->effective_cpus,
1230+
task_cpu_possible_mask(task));
1231+
set_cpus_allowed_ptr(task, new_cpus);
12281232
}
12291233
css_task_iter_end(&it);
12301234
}
@@ -1509,7 +1513,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cs, int cmd,
15091513
spin_unlock_irq(&callback_lock);
15101514

15111515
if (adding || deleting)
1512-
update_tasks_cpumask(parent);
1516+
update_tasks_cpumask(parent, tmp->new_cpus);
15131517

15141518
/*
15151519
* Set or clear CS_SCHED_LOAD_BALANCE when partcmd_update, if necessary.
@@ -1661,7 +1665,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp,
16611665
WARN_ON(!is_in_v2_mode() &&
16621666
!cpumask_equal(cp->cpus_allowed, cp->effective_cpus));
16631667

1664-
update_tasks_cpumask(cp);
1668+
update_tasks_cpumask(cp, tmp->new_cpus);
16651669

16661670
/*
16671671
* On legacy hierarchy, if the effective cpumask of any non-
@@ -2309,7 +2313,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)
23092313
}
23102314
}
23112315

2312-
update_tasks_cpumask(parent);
2316+
update_tasks_cpumask(parent, tmpmask.new_cpus);
23132317

23142318
if (parent->child_ecpus_count)
23152319
update_sibling_cpumasks(parent, cs, &tmpmask);
@@ -3348,7 +3352,7 @@ hotplug_update_tasks_legacy(struct cpuset *cs,
33483352
* as the tasks will be migrated to an ancestor.
33493353
*/
33503354
if (cpus_updated && !cpumask_empty(cs->cpus_allowed))
3351-
update_tasks_cpumask(cs);
3355+
update_tasks_cpumask(cs, new_cpus);
33523356
if (mems_updated && !nodes_empty(cs->mems_allowed))
33533357
update_tasks_nodemask(cs);
33543358

@@ -3385,7 +3389,7 @@ hotplug_update_tasks(struct cpuset *cs,
33853389
spin_unlock_irq(&callback_lock);
33863390

33873391
if (cpus_updated)
3388-
update_tasks_cpumask(cs);
3392+
update_tasks_cpumask(cs, new_cpus);
33893393
if (mems_updated)
33903394
update_tasks_nodemask(cs);
33913395
}

0 commit comments

Comments
 (0)