Re: __GFP_NOFAIL and oom_killer_disabled?

Michal Hocko
2015-02-24T18:14:13Z

On Mon 23-02-15 22:03:25, Tetsuo Handa wrote:
> Michal Hocko wrote:
> > What about something like the following?
>
> I'm fine with whatever approaches as long as retry is guaranteed.
>
> But maybe we can use memory reserves like below?

This sounds too risky to me and not really necessary. GFP_NOFAIL
allocations shouldn't be called while the system is not running any
tasks (aka from pm/device code). So we are primarily trying to help
those nofail allocations which come from kernel threads and their retry
will fail the suspend rather than blow up because of an unexpected
allocation failure.

> I think there will be little risk because userspace processes are
> already frozen...
>
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index a47f0b2..cea0a1b 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -2760,8 +2760,17 @@ retry:
> &did_some_progress);
> if (page)
> goto got_pg;
> - if (!did_some_progress)
> + if (!did_some_progress && !(gfp_mask & __GFP_NOFAIL))
> goto nopage;
> + /*
> + * What!? __GFP_NOFAIL allocation failed to invoke
> + * the OOM killer due to oom_killer_disabled == true?
> + * Then, pretend ALLOC_NO_WATERMARKS request and let
> + * __alloc_pages_high_priority() retry forever...
> + */
> + WARN(1, "Retrying GFP_NOFAIL allocation...\n");
> + gfp_mask &= ~__GFP_NOMEMALLOC;
> + gfp_mask |= __GFP_MEMALLOC;
> }
> /* Wait for some write requests to complete then retry */
> wait_iff_congested(ac->preferred_zone, BLK_RW_ASYNC, HZ/50);

--
Michal Hocko
SUSE Labs