Re: [PATCH v2] cgroup/cpuset: rebind mm mempolicy to effective_mems, not mems_allowed

From: Andrew Morton

Date: Sun Jun 28 2026 - 02:15:28 EST


On Sun, 14 Jun 2026 06:25:55 -0700 Farhad Alemi <farhad.alemi@xxxxxxxxxxxx> wrote:

> Creating a child cpuset where cpuset.mems is never set leads to a div/0
> when a VMA mempolicy with MPOL_F_RELATIVE_NODES rebinds in response to a
> CPU hotplug event.
>
> Reproduction steps:
> 1) Create a cgroup w/ cpuset controls (do not set cpuset.mems)
> 2) Move the task into the child cpuset
> 3) Create a VMA mempolicy for that task with MPOL_F_RELATIVE_NODES
> 4) unplug and hotplug a cpu
> echo 0 > /sys/devices/system/cpu/cpu1/online
> echo 1 > /sys/devices/system/cpu/cpu1/online
> 5) mempolicy rebind does a div/0 in mpol_relative_nodemask on the
> call to __nodes_fold()

Oops.

> The cpuset code passes (cs->mems_allowed) which is not guaranteed to have
> nodes to the rebind routine. Use cs->effective_mems instead, which is
> guaranteed to have a non-empty nodemask.

Well gee, what happened with this patch.

I apologize for misfiling a cc:stable bugfix into my post-rc1 backlog
pile, but I got there in the end.

I guess this is an MM patch, even though it's against
kernel/cgroup/cpuset.c.

Nobody cc'ed Tejun. Fixed.

David acked v1 but is being coy about the v2 patch?

Sashiko AI review suggests that there's a similar bug in
sys_set_mempolicy():

https://sashiko.dev/#/patchset/CA+0ovCgfHJHv5d1mzapWWvF-LhjppzDX8NPPLvCPZxPKg8RiYw@xxxxxxxxxxxxxx


Anyway, I'll queue the v2 patch as an mm.git hotfix, but not with a lot
of confidence at this time. Can people please refocus on this and help
recommend a way forward?


From: Farhad Alemi <farhad.alemi@xxxxxxxxxxxx>
Subject: cgroup/cpuset: rebind mm mempolicy to effective_mems, not mems_allowed
Date: Sun, 14 Jun 2026 06:25:55 -0700

Creating a child cpuset where cpuset.mems is never set leads to a div/0
when a VMA mempolicy with MPOL_F_RELATIVE_NODES rebinds in response to a
CPU hotplug event.

Reproduction steps:
1) Create a cgroup w/ cpuset controls (do not set cpuset.mems)
2) Move the task into the child cpuset
3) Create a VMA mempolicy for that task with MPOL_F_RELATIVE_NODES
4) unplug and hotplug a cpu
echo 0 > /sys/devices/system/cpu/cpu1/online
echo 1 > /sys/devices/system/cpu/cpu1/online
5) mempolicy rebind does a div/0 in mpol_relative_nodemask on the
call to __nodes_fold()

The cpuset code passes (cs->mems_allowed) which is not guaranteed to have
nodes to the rebind routine. Use cs->effective_mems instead, which is
guaranteed to have a non-empty nodemask.

Link: https://lore.kernel.org/linux-mm/CA+0ovCgxbZkXa+OU8w3s84R3KNPNxxRfmsNR-udh+afQBbGNmw@xxxxxxxxxxxxxx/
Link: https://lore.kernel.org/all/CA+0ovCiEz6SP_sn3kN4Tb+_oC=eHMXy_Ffj=usV3wREdQrUtww@xxxxxxxxxxxxxx/
Link: https://lore.kernel.org/CA+0ovCgfHJHv5d1mzapWWvF-LhjppzDX8NPPLvCPZxPKg8RiYw@xxxxxxxxxxxxxx
Fixes: ae1c802382f7 ("cpuset: apply cs->effective_{cpus,mems}")
Signed-off-by: Farhad Alemi <farhad.alemi@xxxxxxxxxxxx>
Suggested-by: Gregory Price <gourry@xxxxxxxxxx>
Suggested-by: Waiman Long <longman@xxxxxxxxxx>
Closes: https://lore.kernel.org/linux-mm/CA+0ovCgxbZkXa+OU8w3s84R3KNPNxxRfmsNR-udh+afQBbGNmw@xxxxxxxxxxxxxx/
Acked-by: Waiman Long <longman@xxxxxxxxxx>
Cc: Alistair Popple <apopple@xxxxxxxxxx>
Cc: Byungchul Park <byungchul@xxxxxx>
Cc: David Hildenbrand <david@xxxxxxxxxx>
Cc: Gregory Price <gourry@xxxxxxxxxx>
Cc: "Huang, Ying" <ying.huang@xxxxxxxxxxxxxxxxx>
Cc: Joshua Hahn <joshua.hahnjy@xxxxxxxxx>
Cc: Matthew Brost <matthew.brost@xxxxxxxxx>
Cc: Rakie Kim <rakie.kim@xxxxxx>
Cc: Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx>
Cc: Zi Yan <ziy@xxxxxxxxxx>
Cc: Tejun Heo <tj@xxxxxxxxxx>
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

kernel/cgroup/cpuset.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/kernel/cgroup/cpuset.c~cgroup-cpuset-rebind-mm-mempolicy-to-effective_mems-not-mems_allowed
+++ a/kernel/cgroup/cpuset.c
@@ -2653,7 +2653,7 @@ void cpuset_update_tasks_nodemask(struct

migrate = is_memory_migrate(cs);

- mpol_rebind_mm(mm, &cs->mems_allowed);
+ mpol_rebind_mm(mm, &cs->effective_mems);
if (migrate)
cpuset_migrate_mm(mm, &cs->old_mems_allowed, &newmems);
else
_