On Fri, Sep 05, 2025 at 10:31:07AM -0700, Shakeel Butt wrote: > On Fri, Sep 05, 2025 at 08:18:25AM -0700, Alexei Starovoitov wrote: > > On Thu, Sep 4, 2025 at 11:20 PM Peilin Ye <yepeilin@xxxxxxxxxx> wrote: > > > As pointed out by Kumar, we can use bpf_mem_alloc() and friends for > > > bpf_hrtimer and bpf_work, to skip memcg accounting. > > > > This is a short term workaround that we shouldn't take. > > Long term bpf_mem_alloc() will use kmalloc_nolock() and > > memcg accounting that was already made to work from any context > > except that the path of memcg_memory_event() wasn't converted. > > > > Shakeel, > > > > Any suggestions how memcg_memory_event()->cgroup_file_notify() > > can be fixed? > > Can we just trylock and skip the event? > > Will !gfpflags_allow_spinning(gfp_mask) be able to detect such call > chains? If yes, then we can change memcg_memory_event() to skip calls to > cgroup_file_notify() if spinning is not allowed. I tried the below diff, but unfortunately __bpf_async_init() calls bpf_map_kmalloc_node() with GFP_ATOMIC, so gfpflags_allow_spinning() would return true. I'll try the trylock-and-skip approach. Thanks, Peilin Ye --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2350,11 +2350,12 @@ static int try_charge_memcg(struct mem_cgroup *memcg, gfp_t gfp_mask, if (unlikely(task_in_memcg_oom(current))) goto nomem; - if (!gfpflags_allow_blocking(gfp_mask)) + if (!gfpflags_allow_blocking(gfp_mask)) { goto nomem; - - memcg_memory_event(mem_over_limit, MEMCG_MAX); - raised_max_event = true; + } else if (gfpflags_allow_spinning(gfp_mask)) { + memcg_memory_event(mem_over_limit, MEMCG_MAX); + raised_max_event = true; + } psi_memstall_enter(&pflags); nr_reclaimed = try_to_free_mem_cgroup_pages(mem_over_limit, nr_pages, @@ -2419,7 +2420,7 @@ static int try_charge_memcg(struct mem_cgroup *memcg, gfp_t gfp_mask, * If the allocation has to be enforced, don't forget to raise * a MEMCG_MAX event. */ - if (!raised_max_event) + if (!raised_max_event && gfpflags_allow_spinning(gfp_mask)) memcg_memory_event(mem_over_limit, MEMCG_MAX); /*