From: Oleg Nesterov Date: Wed, 9 May 2007 09:34:20 +0000 (-0700) Subject: worker_thread: fix racy try_to_freeze() usage X-Git-Tag: v2.6.22-rc1~216 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=85f4186af944c1240c84934a9ab578743df2d69b;p=linux-2.6 worker_thread: fix racy try_to_freeze() usage worker_thread() can miss freeze_process()->signal_wake_up() if it happens between try_to_freeze() and prepare_to_wait(). We should check freezing() before entering schedule(). This race was introduced by me in [PATCH 1/1] workqueue: don't migrate pending works from the dead CPU Looks like mm/vmscan.c:kswapd() has the same race. Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 87693b37d0..63885abf1b 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -308,14 +308,14 @@ static int worker_thread(void *__cwq) do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0); for (;;) { - if (cwq->wq->freezeable) - try_to_freeze(); - prepare_to_wait(&cwq->more_work, &wait, TASK_INTERRUPTIBLE); - if (!cwq->should_stop && list_empty(&cwq->worklist)) + if (!freezing(current) && !cwq->should_stop + && list_empty(&cwq->worklist)) schedule(); finish_wait(&cwq->more_work, &wait); + try_to_freeze(); + if (cwq_should_stop(cwq)) break;