aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-05-06 17:50:48 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-07 15:12:59 -0400
commitb1296cc48b39355241470ef934a5e2270e3f23bd (patch)
treecfaf24de442b9ce19414f67106461f7c4829a1a7
parentd1d241cc2c5feec057c370aa71637380b1b945d5 (diff)
freezer: fix racy usage of try_to_freeze in kswapd
Currently we can miss freeze_process()->signal_wake_up() in kswapd() if it happens between try_to_freeze() and prepare_to_wait(). To prevent this from happening we should check freezing(current) before calling schedule(). Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Cc: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/vmscan.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index db023e2ff385..56651a10c366 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1323,8 +1323,6 @@ static int kswapd(void *p)
1323 for ( ; ; ) { 1323 for ( ; ; ) {
1324 unsigned long new_order; 1324 unsigned long new_order;
1325 1325
1326 try_to_freeze();
1327
1328 prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE); 1326 prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
1329 new_order = pgdat->kswapd_max_order; 1327 new_order = pgdat->kswapd_max_order;
1330 pgdat->kswapd_max_order = 0; 1328 pgdat->kswapd_max_order = 0;
@@ -1335,12 +1333,19 @@ static int kswapd(void *p)
1335 */ 1333 */
1336 order = new_order; 1334 order = new_order;
1337 } else { 1335 } else {
1338 schedule(); 1336 if (!freezing(current))
1337 schedule();
1338
1339 order = pgdat->kswapd_max_order; 1339 order = pgdat->kswapd_max_order;
1340 } 1340 }
1341 finish_wait(&pgdat->kswapd_wait, &wait); 1341 finish_wait(&pgdat->kswapd_wait, &wait);
1342 1342
1343 balance_pgdat(pgdat, order); 1343 if (!try_to_freeze()) {
1344 /* We can speed up thawing tasks if we don't call
1345 * balance_pgdat after returning from the refrigerator
1346 */
1347 balance_pgdat(pgdat, order);
1348 }
1344 } 1349 }
1345 return 0; 1350 return 0;
1346} 1351}