diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2007-05-06 17:50:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-07 15:12:59 -0400 |
commit | b1296cc48b39355241470ef934a5e2270e3f23bd (patch) | |
tree | cfaf24de442b9ce19414f67106461f7c4829a1a7 /mm/vmscan.c | |
parent | d1d241cc2c5feec057c370aa71637380b1b945d5 (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>
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 13 |
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 | } |