From 50814c7f2dda9ba70ce782ed23b47e4f05131dd2 Mon Sep 17 00:00:00 2001 From: Roman Gushchin Date: Mon, 13 May 2024 03:53:23 +0000 Subject: [PATCH] mm: memcontrol: do not miss MEMCG_MAX events for enforced allocations mainline inclusion from mainline-v6.0-rc1 commit d6e103a757fa7876e7ded76128d5dffe12402ab9 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I9ORR4 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d6e103a757fa7876e7ded76128d5dffe12402ab9 -------------------------------- Yafang Shao reported an issue related to the accounting of bpf memory: if a bpf map is charged indirectly for memory consumed from an interrupt context and allocations are enforced, MEMCG_MAX events are not raised. It's not/less of an issue in a generic case because consequent allocations from a process context will trigger the direct reclaim and MEMCG_MAX events will be raised. However a bpf map can belong to a dying/abandoned memory cgroup, so there will be no allocations from a process context and no MEMCG_MAX events will be triggered. Link: https://lkml.kernel.org/r/20220702033521.64630-1-roman.gushchin@linux.dev Signed-off-by: Roman Gushchin Reported-by: Yafang Shao Acked-by: Shakeel Butt Acked-by: Michal Hocko Cc: Johannes Weiner Cc: Muchun Song Signed-off-by: Andrew Morton Conflicts: mm/memcontrol.c [There are context conflicts bacause commit c5c8b16b596e1("mm: memcontrol: fix root_mem_cgroup charging") is not merged. And we merge commit 789303aecf270("mm: vmpressure: don't count proactive reclaim in vmpressure")] Signed-off-by: Cai Xinchen --- mm/memcontrol.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index db44ade93455..88656ed2ad5c 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2674,6 +2674,7 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, bool passed_oom = false; unsigned int reclaim_options = MEMCG_RECLAIM_MAY_SWAP; bool drained = false; + bool raised_max_event = false; unsigned long pflags; if (mem_cgroup_is_root(memcg)) @@ -2724,6 +2725,7 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, goto nomem; memcg_memory_event(mem_over_limit, MEMCG_MAX); + raised_max_event = true; #ifdef CONFIG_PSI_FINE_GRAINED pflags = PSI_MEMCG_RECLAIM; #endif @@ -2787,6 +2789,13 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, if (!(gfp_mask & __GFP_NOFAIL)) return -ENOMEM; force: + /* + * If the allocation has to be enforced, don't forget to raise + * a MEMCG_MAX event. + */ + if (!raised_max_event) + memcg_memory_event(mem_over_limit, MEMCG_MAX); + /* * The allocation either can't fail or will lead to more memory * being freed very soon. Allow memory usage go over the limit -- Gitee