From: Roman Gushchin roman.gushchin@linux.dev
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/?i...
--------------------------------
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 roman.gushchin@linux.dev Reported-by: Yafang Shao laoar.shao@gmail.com Acked-by: Shakeel Butt shakeelb@google.com Acked-by: Michal Hocko mhocko@suse.com Cc: Johannes Weiner hannes@cmpxchg.org Cc: Muchun Song songmuchun@bytedance.com Signed-off-by: Andrew Morton akpm@linux-foundation.org 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 caixinchen1@huawei.com --- 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