diff options
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0063-mm-fix-lost-kswapd-wakeup-in-kswapd_stop.patch')
-rw-r--r-- | recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0063-mm-fix-lost-kswapd-wakeup-in-kswapd_stop.patch | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0063-mm-fix-lost-kswapd-wakeup-in-kswapd_stop.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0063-mm-fix-lost-kswapd-wakeup-in-kswapd_stop.patch new file mode 100644 index 00000000..198dc151 --- /dev/null +++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0063-mm-fix-lost-kswapd-wakeup-in-kswapd_stop.patch | |||
@@ -0,0 +1,84 @@ | |||
1 | From 6ece4e48bfa223f77eff8fc4d2fcc4808214f42e Mon Sep 17 00:00:00 2001 | ||
2 | From: Aaditya Kumar <aaditya.kumar.30@gmail.com> | ||
3 | Date: Tue, 17 Jul 2012 15:48:07 -0700 | ||
4 | Subject: [PATCH 063/109] mm: fix lost kswapd wakeup in kswapd_stop() | ||
5 | |||
6 | commit 1c7e7f6c0703d03af6bcd5ccc11fc15d23e5ecbe upstream. | ||
7 | |||
8 | Offlining memory may block forever, waiting for kswapd() to wake up | ||
9 | because kswapd() does not check the event kthread->should_stop before | ||
10 | sleeping. | ||
11 | |||
12 | The proper pattern, from Documentation/memory-barriers.txt, is: | ||
13 | |||
14 | --- waker --- | ||
15 | event_indicated = 1; | ||
16 | wake_up_process(event_daemon); | ||
17 | |||
18 | --- sleeper --- | ||
19 | for (;;) { | ||
20 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
21 | if (event_indicated) | ||
22 | break; | ||
23 | schedule(); | ||
24 | } | ||
25 | |||
26 | set_current_state() may be wrapped by: | ||
27 | prepare_to_wait(); | ||
28 | |||
29 | In the kswapd() case, event_indicated is kthread->should_stop. | ||
30 | |||
31 | === offlining memory (waker) === | ||
32 | kswapd_stop() | ||
33 | kthread_stop() | ||
34 | kthread->should_stop = 1 | ||
35 | wake_up_process() | ||
36 | wait_for_completion() | ||
37 | |||
38 | === kswapd_try_to_sleep (sleeper) === | ||
39 | kswapd_try_to_sleep() | ||
40 | prepare_to_wait() | ||
41 | . | ||
42 | . | ||
43 | schedule() | ||
44 | . | ||
45 | . | ||
46 | finish_wait() | ||
47 | |||
48 | The schedule() needs to be protected by a test of kthread->should_stop, | ||
49 | which is wrapped by kthread_should_stop(). | ||
50 | |||
51 | Reproducer: | ||
52 | Do heavy file I/O in background. | ||
53 | Do a memory offline/online in a tight loop | ||
54 | |||
55 | Signed-off-by: Aaditya Kumar <aaditya.kumar@ap.sony.com> | ||
56 | Acked-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> | ||
57 | Reviewed-by: Minchan Kim <minchan@kernel.org> | ||
58 | Acked-by: Mel Gorman <mel@csn.ul.ie> | ||
59 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | ||
60 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | ||
61 | Signed-off-by: Ben Hutchings <ben@decadent.org.uk> | ||
62 | --- | ||
63 | mm/vmscan.c | 5 ++++- | ||
64 | 1 files changed, 4 insertions(+), 1 deletions(-) | ||
65 | |||
66 | diff --git a/mm/vmscan.c b/mm/vmscan.c | ||
67 | index 72cf498..8342119 100644 | ||
68 | --- a/mm/vmscan.c | ||
69 | +++ b/mm/vmscan.c | ||
70 | @@ -2824,7 +2824,10 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx) | ||
71 | * them before going back to sleep. | ||
72 | */ | ||
73 | set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold); | ||
74 | - schedule(); | ||
75 | + | ||
76 | + if (!kthread_should_stop()) | ||
77 | + schedule(); | ||
78 | + | ||
79 | set_pgdat_percpu_threshold(pgdat, calculate_pressure_threshold); | ||
80 | } else { | ||
81 | if (remaining) | ||
82 | -- | ||
83 | 1.7.7.6 | ||
84 | |||