From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1030580AbXDJORp (ORCPT ); Tue, 10 Apr 2007 10:17:45 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1030576AbXDJORp (ORCPT ); Tue, 10 Apr 2007 10:17:45 -0400 Received: from ogre.sisk.pl ([217.79.144.158]:60427 "EHLO ogre.sisk.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1030524AbXDJORl (ORCPT ); Tue, 10 Apr 2007 10:17:41 -0400 From: "Rafael J. Wysocki" To: Andrew Morton Subject: [PATCH -mm] freezer: Fix racy usage of try_to_freeze in kswapd Date: Tue, 10 Apr 2007 16:21:16 +0200 User-Agent: KMail/1.9.5 Cc: LKML , Oleg Nesterov , Pavel Machek MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200704101621.16744.rjw@sisk.pl> Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org From: Rafael J. Wysocki 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 --- mm/vmscan.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) Index: linux-2.6.21-rc6/mm/vmscan.c =================================================================== --- linux-2.6.21-rc6.orig/mm/vmscan.c +++ linux-2.6.21-rc6/mm/vmscan.c @@ -1323,8 +1323,6 @@ static int kswapd(void *p) for ( ; ; ) { unsigned long new_order; - try_to_freeze(); - prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE); new_order = pgdat->kswapd_max_order; pgdat->kswapd_max_order = 0; @@ -1335,12 +1333,19 @@ static int kswapd(void *p) */ order = new_order; } else { - schedule(); + if (!freezing(current)) + schedule(); + order = pgdat->kswapd_max_order; } finish_wait(&pgdat->kswapd_wait, &wait); - balance_pgdat(pgdat, order); + if (!try_to_freeze()) { + /* We can speed up thawing tasks if we don't call + * balance_pgdat after returning from the refrigerator + */ + balance_pgdat(pgdat, order); + } } return 0; }