Skip to content

Commit 05ecb68

Browse files
committed
Merge tag 'cgroup-for-6.2-rc7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup fixes from Tejun Heo: "During the v6.2 cycle, there were a series of changes to task cpu affinity handling which fixed cpuset inadvertently clobbering user-configured affinity masks. Unfortunately, they broke the affinity handling on hybrid heterogeneous CPUs which have cores that can execute both 64 and 32bit along with cores that can only execute 32bit code. This contains two fix patches for the above issue. While reverting the changes that caused the regression is definitely an option, the origial patches do improve how cpuset behave signficantly in some cases and the fixes seem fairly safe, so I think it'd be better to try to fix them first" * tag 'cgroup-for-6.2-rc7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: cpuset: Call set_cpus_allowed_ptr() with appropriate mask for task cgroup/cpuset: Don't filter offline CPUs in cpuset_cpus_allowed() for top cpuset tasks
2 parents 66fcf74 + 7a2127e commit 05ecb68

File tree

1 file changed

+36
-9
lines changed

1 file changed

+36
-9
lines changed

kernel/cgroup/cpuset.c

Lines changed: 36 additions & 9 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
}
@@ -3692,15 +3696,38 @@ void __init cpuset_init_smp(void)
36923696
* Description: Returns the cpumask_var_t cpus_allowed of the cpuset
36933697
* attached to the specified @tsk. Guaranteed to return some non-empty
36943698
* subset of cpu_online_mask, even if this means going outside the
3695-
* tasks cpuset.
3699+
* tasks cpuset, except when the task is in the top cpuset.
36963700
**/
36973701

36983702
void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask)
36993703
{
37003704
unsigned long flags;
3705+
struct cpuset *cs;
37013706

37023707
spin_lock_irqsave(&callback_lock, flags);
3703-
guarantee_online_cpus(tsk, pmask);
3708+
rcu_read_lock();
3709+
3710+
cs = task_cs(tsk);
3711+
if (cs != &top_cpuset)
3712+
guarantee_online_cpus(tsk, pmask);
3713+
/*
3714+
* Tasks in the top cpuset won't get update to their cpumasks
3715+
* when a hotplug online/offline event happens. So we include all
3716+
* offline cpus in the allowed cpu list.
3717+
*/
3718+
if ((cs == &top_cpuset) || cpumask_empty(pmask)) {
3719+
const struct cpumask *possible_mask = task_cpu_possible_mask(tsk);
3720+
3721+
/*
3722+
* We first exclude cpus allocated to partitions. If there is no
3723+
* allowable online cpu left, we fall back to all possible cpus.
3724+
*/
3725+
cpumask_andnot(pmask, possible_mask, top_cpuset.subparts_cpus);
3726+
if (!cpumask_intersects(pmask, cpu_online_mask))
3727+
cpumask_copy(pmask, possible_mask);
3728+
}
3729+
3730+
rcu_read_unlock();
37043731
spin_unlock_irqrestore(&callback_lock, flags);
37053732
}
37063733

0 commit comments

Comments
 (0)