From: Mike Waychison <mikew@google.com>
To: Andrew Morton <akpm@linux-foundation.org>,
Mel Gorman <mgorman@suse.de>, Minchan Kim <minchan.kim@gmail.com>,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
Johannes Weiner <jweiner@redhat.com>
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org,
Hugh Dickens <hughd@google.com>, Greg Thelen <gthelen@google.com>,
Mike Waychison <mikew@google.com>
Subject: [PATCH] mm: Fix kswapd livelock on single core, no preempt kernel
Date: Tue, 13 Dec 2011 09:44:31 -0800 [thread overview]
Message-ID: <1323798271-1452-1-git-send-email-mikew@google.com> (raw)
On a single core system with kernel preemption disabled, it is possible
for the memory system to be so taxed that kswapd cannot make any forward
progress. This can happen when most of system memory is tied up as
anonymous memory without swap enabled, causing kswapd to consistently
fail to achieve its watermark goals. In turn, sleeping_prematurely()
will consistently return true and kswapd_try_to_sleep() to never invoke
schedule(). This causes the kswapd thread to stay on the CPU in
perpetuity and keeps other threads from processing oom-kills to reclaim
memory.
The cond_resched() instance in balance_pgdat() is never called as the
loop that iterates from DEF_PRIORITY down to 0 will always set
all_zones_ok to true, and not set it to false once we've passed
DEF_PRIORITY as zones that are marked ->all_unreclaimable are not
considered in the "all_zones_ok" evaluation.
This change modifies kswapd_try_to_sleep to ensure that we enter
scheduler at least once per invocation if needed. This allows kswapd to
get off the CPU and allows other threads to die off from the OOM killer
(freeing memory that is otherwise unavailable in the process).
Signed-off-by: Mike Waychison <mikew@google.com>
---
mm/vmscan.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index f54a05b..aad70c7 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2794,6 +2794,7 @@ out:
static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
{
long remaining = 0;
+ bool slept = false;
DEFINE_WAIT(wait);
if (freezing(current) || kthread_should_stop())
@@ -2806,6 +2807,7 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
remaining = schedule_timeout(HZ/10);
finish_wait(&pgdat->kswapd_wait, &wait);
prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
+ slept = true;
}
/*
@@ -2826,6 +2828,7 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold);
schedule();
set_pgdat_percpu_threshold(pgdat, calculate_pressure_threshold);
+ slept = true;
} else {
if (remaining)
count_vm_event(KSWAPD_LOW_WMARK_HIT_QUICKLY);
@@ -2833,6 +2836,14 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
count_vm_event(KSWAPD_HIGH_WMARK_HIT_QUICKLY);
}
finish_wait(&pgdat->kswapd_wait, &wait);
+ /*
+ * If we did not sleep already, there is a chance that we will sit on
+ * the CPU trashing without making any forward progress. This can
+ * lead to a livelock on a single CPU system without kernel pre-emption,
+ * so introduce a voluntary context switch.
+ */
+ if (!slept)
+ cond_resched();
}
/*
--
1.7.3.1
--
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/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next reply other threads:[~2011-12-13 17:44 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-13 17:44 Mike Waychison [this message]
2011-12-14 2:24 ` [PATCH] mm: Fix kswapd livelock on single core, no preempt kernel Shaohua Li
2011-12-14 4:36 ` Mike Waychison
2011-12-14 4:45 ` Mike Waychison
2011-12-15 1:06 ` Shaohua Li
2011-12-14 12:20 ` Mel Gorman
2011-12-14 15:37 ` Mike Waychison
2011-12-14 10:51 ` James Bottomley
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=1323798271-1452-1-git-send-email-mikew@google.com \
--to=mikew@google.com \
--cc=akpm@linux-foundation.org \
--cc=gthelen@google.com \
--cc=hughd@google.com \
--cc=jweiner@redhat.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mgorman@suse.de \
--cc=minchan.kim@gmail.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).