Oleg pointed out that there is a race at exec time between when bprm->mm is initialized and the exec'ing task being migrated to a different memory control group.
Ractor the code in memcontrol so exec_mmap can use the same code as as fork to ensure that task->memcg == task->mm->memcg. Reported-by: Oleg Nesterov <o...@redhat.com> Signed-off-by: "Eric W. Biederman" <ebied...@xmission.com> --- fs/exec.c | 2 ++ include/linux/memcontrol.h | 5 +++++ mm/memcontrol.c | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index a8be9318d1a8..32461a1543fc 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1044,6 +1044,8 @@ static int exec_mmap(struct mm_struct *mm) return 0; } mmdrop(active_mm); + /* The tsk may have migrated before the new mm was attached */ + mm_sync_memcg_from_task(tsk); return 0; } diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 147e04bfcaee..9b68d9f2740e 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -402,6 +402,7 @@ static inline bool mem_cgroup_is_descendant(struct mem_cgroup *memcg, } void mm_update_memcg(struct mm_struct *mm, struct mem_cgroup *new); +void mm_sync_memcg_from_task(struct task_struct *tsk); static inline bool mm_match_cgroup(struct mm_struct *mm, struct mem_cgroup *memcg) @@ -786,6 +787,10 @@ static inline void mm_update_memcg(struct mm_struct *mm, struct mem_cgroup *new) { } +static inline void mm_sync_memcg_from_task(struct task_struct *tsk) +{ +} + static inline bool mm_match_cgroup(struct mm_struct *mm, struct mem_cgroup *memcg) { diff --git a/mm/memcontrol.c b/mm/memcontrol.c index d74aeba7dfed..552657613c0b 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -5063,7 +5063,7 @@ static void mem_cgroup_attach(struct cgroup_taskset *tset) } } -static void mem_cgroup_fork(struct task_struct *tsk) +void mm_sync_memcg_from_task(struct task_struct *tsk) { struct cgroup_subsys_state *css; @@ -5377,7 +5377,7 @@ struct cgroup_subsys memory_cgrp_subsys = { .attach = mem_cgroup_attach, .cancel_attach = mem_cgroup_cancel_attach, .post_attach = mem_cgroup_move_task, - .fork = mem_cgroup_fork, + .fork = mm_sync_memcg_from_task, .bind = mem_cgroup_bind, .dfl_cftypes = memory_files, .legacy_cftypes = mem_cgroup_legacy_files, -- 2.14.1