Re: [PATCH V3 3/3] mm: page_alloc: drain pcp lists before oom kill

From: Michal Hocko
Date: Thu Nov 09 2023 - 05:33:31 EST


On Sun 05-11-23 18:20:50, Charan Teja Kalla wrote:
> pcp lists are drained from __alloc_pages_direct_reclaim(), only if some
> progress is made in the attempt.
>
> struct page *__alloc_pages_direct_reclaim() {
> .....
> *did_some_progress = __perform_reclaim(gfp_mask, order, ac);
> if (unlikely(!(*did_some_progress)))
> goto out;
> retry:
> page = get_page_from_freelist();
> if (!page && !drained) {
> drain_all_pages(NULL);
> drained = true;
> goto retry;
> }
> out:
> }
>
> After the above, allocation attempt can fallback to
> should_reclaim_retry() to decide reclaim retries. If it too return
> false, allocation request will simply fallback to oom kill path without
> even attempting the draining of the pcp pages that might help the
> allocation attempt to succeed.
>
> VM system running with ~50MB of memory shown the below stats during OOM
> kill:
> Normal free:760kB boost:0kB min:768kB low:960kB high:1152kB
> reserved_highatomic:0KB managed:49152kB free_pcp:460kB
>
> Though in such system state OOM kill is imminent, but the current kill
> could have been delayed if the pcp is drained as pcp + free is even
> above the high watermark.

TBH I am not sure this is really worth it. Does it really reduce the
risk of the OOM in any practical situation?

> Fix this missing drain of pcp list in should_reclaim_retry() along with
> unreserving the high atomic page blocks, like it is done in
> __alloc_pages_direct_reclaim().
>
> Signed-off-by: Charan Teja Kalla <quic_charante@xxxxxxxxxxx>
> ---
> mm/page_alloc.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index b91c99e..8eee292 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -3857,8 +3857,10 @@ should_reclaim_retry(gfp_t gfp_mask, unsigned order,
> cond_resched();
> out:
> /* Before OOM, exhaust highatomic_reserve */
> - if (!ret)
> - return unreserve_highatomic_pageblock(ac, true);
> + if (!ret) {
> + ret = unreserve_highatomic_pageblock(ac, true);
> + drain_all_pages(NULL);
> + }
>
> return ret;
> }
> --
> 2.7.4

--
Michal Hocko
SUSE Labs