From: Michal Hocko <mhocko@suse.cz>
To: linux-mm@kvack.org, Johannes Weiner <hannes@cmpxchg.org>,
Andrew Morton <akpm@linux-foundation.org>,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: LKML <linux-kernel@vger.kernel.org>,
Ying Han <yinghan@google.com>, Hugh Dickins <hughd@google.com>,
Michel Lespinasse <walken@google.com>,
Greg Thelen <gthelen@google.com>,
KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
Tejun Heo <tj@kernel.org>
Subject: [RFC 4/4] mm, memcg: expedite OOM if no memcg is reclaimable
Date: Wed, 11 Dec 2013 15:15:55 +0100 [thread overview]
Message-ID: <1386771355-21805-5-git-send-email-mhocko@suse.cz> (raw)
In-Reply-To: <1386771355-21805-1-git-send-email-mhocko@suse.cz>
Let shrink_zone us know that at least one group has been eligible so
that the caller knows that further attempts to reclaim will not help.
All the shrink_zone callers should back off in such a case. Direct
reclaim should hand over to OOM as soon as possible, kswapd should not
raise the priority and prefferably go to sleep, and the zone reclaim
should just give up without re-trying with higher priority.
Signed-off-by: Michal Hocko <mhocko@suse.cz>
---
mm/vmscan.c | 52 +++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 41 insertions(+), 11 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 234d1690563a..b9e21df2751a 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2167,9 +2167,15 @@ static inline bool should_continue_reclaim(struct zone *zone,
}
}
-static void shrink_zone(struct zone *zone, struct scan_control *sc)
+/*
+ * Returns true if there is at least one lruvec has been scanned.
+ * Always true for !CONFIG_MEMCG otherwise at least one eligible
+ * memcg has to exist (see mem_cgroup_reclaim_eligible).
+ */
+static bool shrink_zone(struct zone *zone, struct scan_control *sc)
{
unsigned long nr_reclaimed, nr_scanned;
+ int groups_reclaimed = 0;
do {
struct mem_cgroup *root = sc->target_mem_cgroup;
@@ -2200,6 +2206,7 @@ static void shrink_zone(struct zone *zone, struct scan_control *sc)
continue;
}
+ groups_reclaimed++;
lruvec = mem_cgroup_zone_lruvec(zone, memcg);
shrink_lruvec(lruvec, sc);
@@ -2226,8 +2233,12 @@ static void shrink_zone(struct zone *zone, struct scan_control *sc)
sc->nr_scanned - nr_scanned,
sc->nr_reclaimed - nr_reclaimed);
+ if (!groups_reclaimed)
+ break;
} while (should_continue_reclaim(zone, sc->nr_reclaimed - nr_reclaimed,
sc->nr_scanned - nr_scanned, sc));
+
+ return groups_reclaimed > 0;
}
/* Returns true if compaction should go ahead for a high-order request */
@@ -2347,7 +2358,9 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc)
/* need some check for avoid more shrink_zone() */
}
- shrink_zone(zone, sc);
+ /* No memcg to reclaim from so bail out */
+ if (!shrink_zone(zone, sc))
+ break;
}
return aborted_reclaim;
@@ -2442,6 +2455,17 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
goto out;
/*
+ * If the target memcg is not eligible for reclaim then we have
+ * no option but OOM
+ */
+ if (!sc->nr_scanned &&
+ mem_cgroup_reclaim_no_eligible(
+ sc->target_mem_cgroup)) {
+ delayacct_freepages_end();
+ return 0;
+ }
+
+ /*
* If we're getting trouble reclaiming, start doing
* writepage even in laptop mode.
*/
@@ -2481,13 +2505,6 @@ out:
if (aborted_reclaim)
return 1;
- /*
- * If the target memcg is not eligible for reclaim then we have no opetion
- * but OOM
- */
- if (!sc->nr_scanned && mem_cgroup_reclaim_no_eligible(sc->target_mem_cgroup))
- return 0;
-
/* top priority shrink_zones still had more to do? don't OOM, then */
if (global_reclaim(sc) && !all_unreclaimable(zonelist, sc))
return 1;
@@ -2772,6 +2789,17 @@ static bool pgdat_balanced(pg_data_t *pgdat, int order, int classzone_idx)
unsigned long balanced_pages = 0;
int i;
+
+ /*
+ * If no memcg is eligible to reclaim then we end up scanning nothing
+ * and so it doesn't make any sense to do any scanning in the first
+ * place. So let's go to sleep and pretend everything is balanced.
+ * We rely on the direct reclaim to eventually sort out the situation
+ * e.g. by triggering OOM killer.
+ */
+ if (mem_cgroup_reclaim_no_eligible(NULL))
+ return true;
+
/* Check the watermark levels */
for (i = 0; i <= classzone_idx; i++) {
struct zone *zone = pgdat->node_zones + i;
@@ -3115,7 +3143,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
* Raise priority if scanning rate is too low or there was no
* progress in reclaiming pages
*/
- if (raise_priority || !sc.nr_reclaimed)
+ if (raise_priority || (sc.nr_scanned && !sc.nr_reclaimed))
sc.priority--;
} while (sc.priority >= 1 &&
!pgdat_balanced(pgdat, order, *classzone_idx));
@@ -3572,7 +3600,9 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
* priorities until we have enough memory freed.
*/
do {
- shrink_zone(zone, &sc);
+ /* memcg to reclaim from so bail out */
+ if(!shrink_zone(zone, &sc))
+ break;
} while (sc.nr_reclaimed < nr_pages && --sc.priority >= 0);
}
--
1.8.4.4
--
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:[~2013-12-11 14:16 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-11 14:15 [RFC 0/4] memcg: Low-limit reclaim Michal Hocko
2013-12-11 14:15 ` [RFC 1/4] memcg, mm: introduce lowlimit reclaim Michal Hocko
2013-12-11 14:15 ` [RFC 2/4] mm, memcg: allow OOM if no memcg is eligible during direct reclaim Michal Hocko
2013-12-11 14:15 ` [RFC 3/4] memcg: Allow setting low_limit Michal Hocko
2013-12-11 14:15 ` Michal Hocko [this message]
2014-01-24 11:07 ` [RFC 0/4] memcg: Low-limit reclaim Roman Gushchin
2014-01-29 18:22 ` Michal Hocko
2014-02-12 12:28 ` Roman Gushchin
2014-02-13 16:12 ` Michal Hocko
2014-01-29 19:08 ` Greg Thelen
2014-01-30 12:30 ` Michal Hocko
2014-01-31 0:28 ` Greg Thelen
2014-02-03 14:43 ` Michal Hocko
2014-02-04 1:33 ` Greg Thelen
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=1386771355-21805-5-git-send-email-mhocko@suse.cz \
--to=mhocko@suse.cz \
--cc=akpm@linux-foundation.org \
--cc=gthelen@google.com \
--cc=hannes@cmpxchg.org \
--cc=hughd@google.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=kosaki.motohiro@jp.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=tj@kernel.org \
--cc=walken@google.com \
--cc=yinghan@google.com \
/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;
as well as URLs for NNTP newsgroup(s).