From: David Rientjes <rientjes@google.com>
To: Michal Hocko <mhocko@kernel.org>
Cc: linux-mm@kvack.org, Andrew Morton <akpm@linux-foundation.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Mel Gorman <mgorman@suse.de>,
Johannes Weiner <hannes@cmpxchg.org>,
Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>,
Hillf Danton <hillf.zj@alibaba-inc.com>,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
Michal Hocko <mhocko@suse.com>
Subject: Re: [RFC 1/3] mm, oom: refactor oom detection
Date: Thu, 19 Nov 2015 15:01:38 -0800 (PST) [thread overview]
Message-ID: <alpine.DEB.2.10.1511191455310.17510@chino.kir.corp.google.com> (raw)
In-Reply-To: <1447851840-15640-2-git-send-email-mhocko@kernel.org>
On Wed, 18 Nov 2015, Michal Hocko wrote:
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 8034909faad2..020c005c5bc0 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -2992,6 +2992,13 @@ static inline bool is_thp_gfp_mask(gfp_t gfp_mask)
> return (gfp_mask & (GFP_TRANSHUGE | __GFP_KSWAPD_RECLAIM)) == GFP_TRANSHUGE;
> }
>
> +/*
> + * Number of backoff steps for potentially reclaimable pages if the direct reclaim
> + * cannot make any progress. Each step will reduce 1/MAX_STALL_BACKOFF of the
> + * reclaimable memory.
> + */
> +#define MAX_STALL_BACKOFF 16
> +
> static inline struct page *
> __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
> struct alloc_context *ac)
> @@ -3004,6 +3011,9 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
> enum migrate_mode migration_mode = MIGRATE_ASYNC;
> bool deferred_compaction = false;
> int contended_compaction = COMPACT_CONTENDED_NONE;
> + struct zone *zone;
> + struct zoneref *z;
> + int stall_backoff = 0;
>
> /*
> * In the slowpath, we sanity check order to avoid ever trying to
> @@ -3155,13 +3165,57 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
> if (gfp_mask & __GFP_NORETRY)
> goto noretry;
>
> - /* Keep reclaiming pages as long as there is reasonable progress */
> + /*
> + * Do not retry high order allocations unless they are __GFP_REPEAT
> + * and even then do not retry endlessly unless explicitly told so
> + */
> pages_reclaimed += did_some_progress;
> - if ((did_some_progress && order <= PAGE_ALLOC_COSTLY_ORDER) ||
> - ((gfp_mask & __GFP_REPEAT) && pages_reclaimed < (1 << order))) {
> - /* Wait for some write requests to complete then retry */
> - wait_iff_congested(ac->preferred_zone, BLK_RW_ASYNC, HZ/50);
> - goto retry;
> + if (order > PAGE_ALLOC_COSTLY_ORDER) {
> + if (!(gfp_mask & __GFP_NOFAIL) &&
> + (!(gfp_mask & __GFP_REPEAT) || pages_reclaimed >= (1<<order)))
> + goto noretry;
> +
> + if (did_some_progress)
> + goto retry;
> + }
First of all, thanks very much for attacking this issue!
I'm concerned that we'll reach stall_backoff == MAX_STALL_BACKOFF too
quickly if the wait_iff_congested() is removed. While not immediately
being available for reclaim, this has at least partially stalled in the
past which may have resulted in external memory freeing. I'm wondering if
it would make sense to keep if nothing more than to avoid an immediate
retry.
> +
> + /*
> + * Be optimistic and consider all pages on reclaimable LRUs as usable
> + * but make sure we converge to OOM if we cannot make any progress after
> + * multiple consecutive failed attempts.
> + */
> + if (did_some_progress)
> + stall_backoff = 0;
> + else
> + stall_backoff = min(stall_backoff+1, MAX_STALL_BACKOFF);
> +
> + /*
> + * Keep reclaiming pages while there is a chance this will lead somewhere.
> + * If none of the target zones can satisfy our allocation request even
> + * if all reclaimable pages are considered then we are screwed and have
> + * to go OOM.
> + */
> + for_each_zone_zonelist_nodemask(zone, z, ac->zonelist, ac->high_zoneidx, ac->nodemask) {
> + unsigned long free = zone_page_state(zone, NR_FREE_PAGES);
This is concerning, I would think that you would want to use
zone_page_state_snapshot() at the very list for when
stall_backoff == MAX_STALL_BACKOFF.
> + unsigned long reclaimable;
> + unsigned long target;
> +
> + reclaimable = zone_reclaimable_pages(zone) +
> + zone_page_state(zone, NR_ISOLATED_FILE) +
> + zone_page_state(zone, NR_ISOLATED_ANON);
Does NR_ISOLATED_ANON mean anything relevant here in swapless
environments?
> + target = reclaimable;
> + target -= DIV_ROUND_UP(stall_backoff * target, MAX_STALL_BACKOFF);
> + target += free;
> +
> + /*
> + * Would the allocation succeed if we reclaimed the whole target?
> + */
> + if (__zone_watermark_ok(zone, order, min_wmark_pages(zone),
> + ac->high_zoneidx, alloc_flags, target)) {
> + /* Wait for some write requests to complete then retry */
> + wait_iff_congested(zone, BLK_RW_ASYNC, HZ/50);
> + goto retry;
> + }
> }
>
> /* Reclaim has failed us, start killing things */
> @@ -3170,8 +3224,10 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
> goto got_pg;
>
> /* Retry as long as the OOM killer is making progress */
> - if (did_some_progress)
> + if (did_some_progress) {
> + stall_backoff = 0;
> goto retry;
> + }
>
> noretry:
> /*
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index a4507ecaefbf..9060a71e5a90 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -192,7 +192,7 @@ static bool sane_reclaim(struct scan_control *sc)
> }
> #endif
>
> -static unsigned long zone_reclaimable_pages(struct zone *zone)
> +unsigned long zone_reclaimable_pages(struct zone *zone)
> {
> unsigned long nr;
>
> @@ -2594,10 +2594,6 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc)
>
> if (shrink_zone(zone, sc, zone_idx(zone) == classzone_idx))
> reclaimable = true;
> -
> - if (global_reclaim(sc) &&
> - !reclaimable && zone_reclaimable(zone))
> - reclaimable = true;
> }
>
> /*
It's possible to just make shrink_zones() void and drop the reclaimable
variable.
Otherwise looks good!
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2015-11-19 23:01 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-18 13:03 [RFC 0/3] OOM detection rework v2 Michal Hocko
2015-11-18 13:03 ` [RFC 1/3] mm, oom: refactor oom detection Michal Hocko
2015-11-19 23:01 ` David Rientjes [this message]
2015-11-20 9:06 ` Michal Hocko
2015-11-20 23:27 ` David Rientjes
2015-11-23 9:41 ` Michal Hocko
2015-11-23 18:24 ` Johannes Weiner
2015-11-24 10:03 ` Michal Hocko
2015-11-18 13:03 ` [RFC 2/3] mm: throttle on IO only when there are too many dirty and writeback pages Michal Hocko
2015-11-19 23:12 ` David Rientjes
2015-11-20 9:15 ` Michal Hocko
2015-11-18 13:04 ` [RFC 3/3] mm: use watermak checks for __GFP_REPEAT high order allocations Michal Hocko
2015-11-19 23:17 ` David Rientjes
2015-11-20 9:18 ` Michal Hocko
2015-11-20 23:33 ` David Rientjes
2015-11-23 9:46 ` Michal Hocko
2015-11-18 16:21 ` [RFC 0/3] OOM detection rework v2 Linus Torvalds
-- strict thread matches above, loose matches on Subject: below --
2015-12-01 12:56 [RFC 0/3] OOM detection rework v3 Michal Hocko
2015-12-01 12:56 ` [RFC 1/3] mm, oom: refactor oom detection Michal Hocko
2015-12-11 16:16 ` Johannes Weiner
2015-12-14 18:34 ` Michal Hocko
2015-10-29 15:17 RFC: OOM detection rework v1 mhocko
2015-10-29 15:17 ` [RFC 1/3] mm, oom: refactor oom detection mhocko
2015-10-30 4:10 ` Hillf Danton
2015-10-30 8:36 ` Michal Hocko
2015-10-30 10:14 ` Michal Hocko
2015-10-30 13:32 ` Tetsuo Handa
2015-10-30 14:55 ` Michal Hocko
2015-10-31 3:57 ` Hillf Danton
2015-10-30 5:23 ` Kamezawa Hiroyuki
2015-10-30 8:23 ` Michal Hocko
2015-10-30 9:41 ` Kamezawa Hiroyuki
2015-10-30 10:18 ` Michal Hocko
2015-11-12 12:39 ` Michal Hocko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.DEB.2.10.1511191455310.17510@chino.kir.corp.google.com \
--to=rientjes@google.com \
--cc=akpm@linux-foundation.org \
--cc=hannes@cmpxchg.org \
--cc=hillf.zj@alibaba-inc.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=linux-mm@kvack.org \
--cc=mgorman@suse.de \
--cc=mhocko@kernel.org \
--cc=mhocko@suse.com \
--cc=penguin-kernel@i-love.sakura.ne.jp \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox