* [PATCH v2 1/2] memcg, oom: remove unnecessary check in mem_cgroup_oom_synchronize() [not found] <ZDUxVG2otm5i12o2@dhcp22.suse.cz> @ 2023-04-19 3:07 ` Haifeng Xu 2023-04-19 7:35 ` Michal Hocko 2023-04-19 3:07 ` [PATCH v2 2/2] memcg, oom: remove explicit wakeup " Haifeng Xu 1 sibling, 1 reply; 4+ messages in thread From: Haifeng Xu @ 2023-04-19 3:07 UTC (permalink / raw) To: mhocko Cc: hannes, roman.gushchin, shakeelb, akpm, linux-mm, linux-kernel, Haifeng Xu mem_cgroup_oom_synchronize() is only used when the memcg oom handling is handed over to the edge of the #PF path. Since commit 29ef680ae7c2 ("memcg, oom: move out_of_memory back to the charge path") this is the case only when the kernel memcg oom killer is disabled (current->memcg_in_oom is only set if memcg->oom_kill_disable). Therefore a check for oom_kill_disable in mem_cgroup_oom_synchronize() is not required. Signed-off-by: Haifeng Xu <haifeng.xu@shopee.com> Suggested-by: Michal Hocko <mhocko@suse.com> --- v2: split original into two and improve patch description --- mm/memcontrol.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 5abffe6f8389..fbf4d2bb1003 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1999,16 +1999,9 @@ bool mem_cgroup_oom_synchronize(bool handle) if (locked) mem_cgroup_oom_notify(memcg); - if (locked && !memcg->oom_kill_disable) { - mem_cgroup_unmark_under_oom(memcg); - finish_wait(&memcg_oom_waitq, &owait.wait); - mem_cgroup_out_of_memory(memcg, current->memcg_oom_gfp_mask, - current->memcg_oom_order); - } else { - schedule(); - mem_cgroup_unmark_under_oom(memcg); - finish_wait(&memcg_oom_waitq, &owait.wait); - } + schedule(); + mem_cgroup_unmark_under_oom(memcg); + finish_wait(&memcg_oom_waitq, &owait.wait); if (locked) { mem_cgroup_oom_unlock(memcg); -- 2.25.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2 1/2] memcg, oom: remove unnecessary check in mem_cgroup_oom_synchronize() 2023-04-19 3:07 ` [PATCH v2 1/2] memcg, oom: remove unnecessary check in mem_cgroup_oom_synchronize() Haifeng Xu @ 2023-04-19 7:35 ` Michal Hocko 0 siblings, 0 replies; 4+ messages in thread From: Michal Hocko @ 2023-04-19 7:35 UTC (permalink / raw) To: Haifeng Xu; +Cc: hannes, roman.gushchin, shakeelb, akpm, linux-mm, linux-kernel On Wed 19-04-23 03:07:38, Haifeng Xu wrote: > mem_cgroup_oom_synchronize() is only used when the memcg oom handling is > handed over to the edge of the #PF path. Since commit 29ef680ae7c2 ("memcg, > oom: move out_of_memory back to the charge path") this is the case only > when the kernel memcg oom killer is disabled (current->memcg_in_oom is > only set if memcg->oom_kill_disable). Therefore a check for > oom_kill_disable in mem_cgroup_oom_synchronize() is not required. > > Signed-off-by: Haifeng Xu <haifeng.xu@shopee.com> > Suggested-by: Michal Hocko <mhocko@suse.com> Acked-by: Michal Hocko <mhocko@suse.com> > --- > v2: split original into two and improve patch description > --- > mm/memcontrol.c | 13 +++---------- > 1 file changed, 3 insertions(+), 10 deletions(-) > > diff --git a/mm/memcontrol.c b/mm/memcontrol.c > index 5abffe6f8389..fbf4d2bb1003 100644 > --- a/mm/memcontrol.c > +++ b/mm/memcontrol.c > @@ -1999,16 +1999,9 @@ bool mem_cgroup_oom_synchronize(bool handle) > if (locked) > mem_cgroup_oom_notify(memcg); > > - if (locked && !memcg->oom_kill_disable) { > - mem_cgroup_unmark_under_oom(memcg); > - finish_wait(&memcg_oom_waitq, &owait.wait); > - mem_cgroup_out_of_memory(memcg, current->memcg_oom_gfp_mask, > - current->memcg_oom_order); > - } else { > - schedule(); > - mem_cgroup_unmark_under_oom(memcg); > - finish_wait(&memcg_oom_waitq, &owait.wait); > - } > + schedule(); > + mem_cgroup_unmark_under_oom(memcg); > + finish_wait(&memcg_oom_waitq, &owait.wait); > > if (locked) { > mem_cgroup_oom_unlock(memcg); > -- > 2.25.1 -- Michal Hocko SUSE Labs ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] memcg, oom: remove explicit wakeup in mem_cgroup_oom_synchronize() [not found] <ZDUxVG2otm5i12o2@dhcp22.suse.cz> 2023-04-19 3:07 ` [PATCH v2 1/2] memcg, oom: remove unnecessary check in mem_cgroup_oom_synchronize() Haifeng Xu @ 2023-04-19 3:07 ` Haifeng Xu 2023-04-19 7:38 ` Michal Hocko 1 sibling, 1 reply; 4+ messages in thread From: Haifeng Xu @ 2023-04-19 3:07 UTC (permalink / raw) To: mhocko Cc: hannes, roman.gushchin, shakeelb, akpm, linux-mm, linux-kernel, Haifeng Xu Before commit 29ef680ae7c2 ("memcg, oom: move out_of_memory back to the charge path"), all memcg oom killers were delayed to page fault path. And the explicit wakeup is used in this case: thread A: ... if (locked) { // complete oom-kill, hold the lock mem_cgroup_oom_unlock(memcg); ... } ... thread B: ... if (locked && !memcg->oom_kill_disable) { ... } else { schedule(); // can't acquire the lock ... } ... The reason is that thread A kicks off the OOM-killer, which leads to wakeups from the uncharges of the exiting task. But thread B is not guaranteed to see them if it enters the OOM path after the OOM kills but before thread A releases the lock. Now only oom_kill_disable case is handled from the #PF path. In that case it is userspace to trigger the wake up not the #PF path itself. All potential paths to free some charges are responsible to call memcg_oom_recover() , so the explicit wakeup is not needed in the mem_cgroup_oom_synchronize() path which doesn't release any memory itself. Signed-off-by: Haifeng Xu <haifeng.xu@shopee.com> Suggested-by: Michal Hocko <mhocko@suse.com> --- v2: split original into two and improve patch description --- mm/memcontrol.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index fbf4d2bb1003..710ce3e7824f 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2003,15 +2003,8 @@ bool mem_cgroup_oom_synchronize(bool handle) mem_cgroup_unmark_under_oom(memcg); finish_wait(&memcg_oom_waitq, &owait.wait); - if (locked) { + if (locked) mem_cgroup_oom_unlock(memcg); - /* - * There is no guarantee that an OOM-lock contender - * sees the wakeups triggered by the OOM kill - * uncharges. Wake any sleepers explicitly. - */ - memcg_oom_recover(memcg); - } cleanup: current->memcg_in_oom = NULL; css_put(&memcg->css); -- 2.25.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2 2/2] memcg, oom: remove explicit wakeup in mem_cgroup_oom_synchronize() 2023-04-19 3:07 ` [PATCH v2 2/2] memcg, oom: remove explicit wakeup " Haifeng Xu @ 2023-04-19 7:38 ` Michal Hocko 0 siblings, 0 replies; 4+ messages in thread From: Michal Hocko @ 2023-04-19 7:38 UTC (permalink / raw) To: Haifeng Xu; +Cc: hannes, roman.gushchin, shakeelb, akpm, linux-mm, linux-kernel On Wed 19-04-23 03:07:39, Haifeng Xu wrote: > Before commit 29ef680ae7c2 ("memcg, oom: move out_of_memory back to > the charge path"), all memcg oom killers were delayed to page fault > path. And the explicit wakeup is used in this case: > > thread A: > ... > if (locked) { // complete oom-kill, hold the lock > mem_cgroup_oom_unlock(memcg); > ... > } > ... > > thread B: > ... > > if (locked && !memcg->oom_kill_disable) { > ... > } else { > schedule(); // can't acquire the lock > ... > } > ... > > The reason is that thread A kicks off the OOM-killer, which leads to > wakeups from the uncharges of the exiting task. But thread B is not > guaranteed to see them if it enters the OOM path after the OOM kills > but before thread A releases the lock. > > Now only oom_kill_disable case is handled from the #PF path. In that > case it is userspace to trigger the wake up not the #PF path itself. > All potential paths to free some charges are responsible to call > memcg_oom_recover() , so the explicit wakeup is not needed in the > mem_cgroup_oom_synchronize() path which doesn't release any memory > itself. > > Signed-off-by: Haifeng Xu <haifeng.xu@shopee.com> > Suggested-by: Michal Hocko <mhocko@suse.com> I hope I haven't missed anything but this looks good to me. One way to test this would be a parallel OOM triggering workload which uses page faults and an automatic user space driven oom killer (detect under_oom and send SIGKILL to a random task after a random timeout). Objective is that no task gets stuck in mem_cgroup_oom_synchronize. I am pretty sure this could be easily turned into a selftest. Acked-by: Michal Hocko <mhocko@suse.com> > --- > v2: split original into two and improve patch description > --- > mm/memcontrol.c | 9 +-------- > 1 file changed, 1 insertion(+), 8 deletions(-) > > diff --git a/mm/memcontrol.c b/mm/memcontrol.c > index fbf4d2bb1003..710ce3e7824f 100644 > --- a/mm/memcontrol.c > +++ b/mm/memcontrol.c > @@ -2003,15 +2003,8 @@ bool mem_cgroup_oom_synchronize(bool handle) > mem_cgroup_unmark_under_oom(memcg); > finish_wait(&memcg_oom_waitq, &owait.wait); > > - if (locked) { > + if (locked) > mem_cgroup_oom_unlock(memcg); > - /* > - * There is no guarantee that an OOM-lock contender > - * sees the wakeups triggered by the OOM kill > - * uncharges. Wake any sleepers explicitly. > - */ > - memcg_oom_recover(memcg); > - } > cleanup: > current->memcg_in_oom = NULL; > css_put(&memcg->css); > -- > 2.25.1 -- Michal Hocko SUSE Labs ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-04-19 7:38 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <ZDUxVG2otm5i12o2@dhcp22.suse.cz>
2023-04-19 3:07 ` [PATCH v2 1/2] memcg, oom: remove unnecessary check in mem_cgroup_oom_synchronize() Haifeng Xu
2023-04-19 7:35 ` Michal Hocko
2023-04-19 3:07 ` [PATCH v2 2/2] memcg, oom: remove explicit wakeup " Haifeng Xu
2023-04-19 7:38 ` Michal Hocko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox