public inbox for linux-pm@vger.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: pm list <linux-pm@lists.linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Matthew Wilcox <matthew@wil.cx>,
	LKML <linux-kernel@vger.kernel.org>,
	Cedric Le Goater <clg@fr.ibm.com>,
	Liam Howlett <howlett@gmail.com>, Ingo Molnar <mingo@elte.hu>,
	Paul Menage <menage@google.com>
Subject: [RFC][PATCH 2/2] Freezer: Try to handle killable tasks
Date: Wed, 7 May 2008 00:07:55 +0200	[thread overview]
Message-ID: <200805070007.56998.rjw@sisk.pl> (raw)
In-Reply-To: <200805070003.56387.rjw@sisk.pl>

From: Rafael J. Wysocki <rjw@sisk.pl>

The introduction of TASK_KILLABLE allows the freezer to work in some situation
that it could not handle before.

Make the freezer handle killable tasks and add try_to_freeze() in some places
where it is safe to freeze a (killable) task.  Introduce the
wait_event_killable_freezable() macro to be used wherever the freezing of
a waiting killable task is desirable.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
 fs/nfs/inode.c          |    2 ++
 fs/nfs/nfs3proc.c       |    2 ++
 fs/nfs/nfs4proc.c       |    4 ++++
 fs/nfs/pagelist.c       |    8 ++++++--
 fs/smbfs/request.c      |    2 ++
 include/linux/freezer.h |   20 +++++++++++++++++---
 kernel/mutex.c          |    3 +++
 kernel/power/process.c  |    6 ++++--
 kernel/sched.c          |    2 ++
 net/sunrpc/sched.c      |    2 ++
 10 files changed, 44 insertions(+), 7 deletions(-)

Index: linux-2.6/fs/nfs/nfs3proc.c
===================================================================
--- linux-2.6.orig/fs/nfs/nfs3proc.c
+++ linux-2.6/fs/nfs/nfs3proc.c
@@ -17,6 +17,7 @@
 #include <linux/nfs_page.h>
 #include <linux/lockd/bind.h>
 #include <linux/nfs_mount.h>
+#include <linux/freezer.h>
 
 #include "iostat.h"
 #include "internal.h"
@@ -33,6 +34,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, 
 		if (res != -EJUKEBOX)
 			break;
 		schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
+		try_to_freeze();
 		res = -ERESTARTSYS;
 	} while (!fatal_signal_pending(current));
 	return res;
Index: linux-2.6/fs/nfs/nfs4proc.c
===================================================================
--- linux-2.6.orig/fs/nfs/nfs4proc.c
+++ linux-2.6/fs/nfs/nfs4proc.c
@@ -48,6 +48,7 @@
 #include <linux/smp_lock.h>
 #include <linux/namei.h>
 #include <linux/mount.h>
+#include <linux/freezer.h>
 
 #include "nfs4_fs.h"
 #include "delegation.h"
@@ -2788,6 +2789,7 @@ static int nfs4_wait_bit_killable(void *
 	if (fatal_signal_pending(current))
 		return -ERESTARTSYS;
 	schedule();
+	try_to_freeze();
 	return 0;
 }
 
@@ -2819,6 +2821,8 @@ static int nfs4_delay(struct rpc_clnt *c
 	schedule_timeout_killable(*timeout);
 	if (fatal_signal_pending(current))
 		res = -ERESTARTSYS;
+	else
+		try_to_freeze();
 	*timeout <<= 1;
 	return res;
 }
Index: linux-2.6/fs/nfs/pagelist.c
===================================================================
--- linux-2.6.orig/fs/nfs/pagelist.c
+++ linux-2.6/fs/nfs/pagelist.c
@@ -18,6 +18,7 @@
 #include <linux/nfs_page.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs_mount.h>
+#include <linux/freezer.h>
 
 #include "internal.h"
 
@@ -68,6 +69,7 @@ nfs_create_request(struct nfs_open_conte
 
 		if (fatal_signal_pending(current))
 			return ERR_PTR(-ERESTARTSYS);
+		try_to_freeze();
 		yield();
 	}
 
@@ -180,10 +182,12 @@ static int nfs_wait_bit_killable(void *w
 {
 	int ret = 0;
 
-	if (fatal_signal_pending(current))
+	if (fatal_signal_pending(current)) {
 		ret = -ERESTARTSYS;
-	else
+	} else {
 		schedule();
+		try_to_freeze();
+	}
 	return ret;
 }
 
Index: linux-2.6/fs/smbfs/request.c
===================================================================
--- linux-2.6.orig/fs/smbfs/request.c
+++ linux-2.6/fs/smbfs/request.c
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/net.h>
 #include <linux/sched.h>
+#include <linux/freezer.h>
 
 #include <linux/smb_fs.h>
 #include <linux/smbno.h>
@@ -109,6 +110,7 @@ struct smb_request *smb_alloc_request(st
 			return ERR_PTR(-ERESTARTSYS);
 		current->policy = SCHED_YIELD;
 		schedule();
+		try_to_freeze();
 #else
 		/* FIXME: we want something like nfs does above, but that
 		   requires changes to all callers and can wait. */
Index: linux-2.6/include/linux/freezer.h
===================================================================
--- linux-2.6.orig/include/linux/freezer.h
+++ linux-2.6/include/linux/freezer.h
@@ -137,8 +137,9 @@ static inline void set_freezable_with_si
 }
 
 /*
- * Freezer-friendly wrappers around wait_event_interruptible() and
- * wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
+ * Freezer-friendly wrappers around wait_event_interruptible(),
+ * wait_event_interruptible_timeout(), wait_event_killable(),
+ * originally defined in <linux/wait.h>
  */
 
 #define wait_event_freezable(wq, condition)				\
@@ -155,7 +156,6 @@ static inline void set_freezable_with_si
 	__retval;							\
 })
 
-
 #define wait_event_freezable_timeout(wq, condition, timeout)		\
 ({									\
 	long __retval = timeout;					\
@@ -166,6 +166,20 @@ static inline void set_freezable_with_si
 	} while (try_to_freeze());					\
 	__retval;							\
 })
+
+#define wait_event_killable_freezable(wq, condition)				\
+({									\
+	int __retval;							\
+	do {								\
+		__retval = wait_event_killable(wq, 			\
+				(condition) || freezing(current));	\
+		if (__retval && !freezing(current))			\
+			break;						\
+		else if (!(condition))					\
+			__retval = -ERESTARTSYS;			\
+	} while (try_to_freeze());					\
+	__retval;							\
+})
 #else /* !CONFIG_PM_SLEEP */
 static inline int frozen(struct task_struct *p) { return 0; }
 static inline int freezing(struct task_struct *p) { return 0; }
Index: linux-2.6/kernel/mutex.c
===================================================================
--- linux-2.6.orig/kernel/mutex.c
+++ linux-2.6/kernel/mutex.c
@@ -18,6 +18,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/debug_locks.h>
+#include <linux/freezer.h>
 
 /*
  * In the DEBUG case we are using the "NULL fastpath" for mutexes,
@@ -182,6 +183,8 @@ __mutex_lock_common(struct mutex *lock, 
 		/* didnt get the lock, go to sleep: */
 		spin_unlock_mutex(&lock->wait_lock, flags);
 		schedule();
+		if (state == TASK_KILLABLE)
+			try_to_freeze();
 		spin_lock_mutex(&lock->wait_lock, flags);
 	}
 
Index: linux-2.6/kernel/sched.c
===================================================================
--- linux-2.6.orig/kernel/sched.c
+++ linux-2.6/kernel/sched.c
@@ -4769,6 +4769,8 @@ do_wait_for_common(struct completion *x,
 			__set_current_state(state);
 			spin_unlock_irq(&x->wait.lock);
 			timeout = schedule_timeout(timeout);
+			if (state == TASK_KILLABLE)
+				try_to_freeze();
 			spin_lock_irq(&x->wait.lock);
 			if (!timeout) {
 				__remove_wait_queue(&x->wait, &wait);
Index: linux-2.6/net/sunrpc/sched.c
===================================================================
--- linux-2.6.orig/net/sunrpc/sched.c
+++ linux-2.6/net/sunrpc/sched.c
@@ -19,6 +19,7 @@
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
+#include <linux/freezer.h>
 
 #include <linux/sunrpc/clnt.h>
 
@@ -227,6 +228,7 @@ static int rpc_wait_bit_killable(void *w
 	if (fatal_signal_pending(current))
 		return -ERESTARTSYS;
 	schedule();
+	try_to_freeze();
 	return 0;
 }
 
Index: linux-2.6/fs/nfs/inode.c
===================================================================
--- linux-2.6.orig/fs/nfs/inode.c
+++ linux-2.6/fs/nfs/inode.c
@@ -37,6 +37,7 @@
 #include <linux/vfs.h>
 #include <linux/inet.h>
 #include <linux/nfs_xdr.h>
+#include <linux/freezer.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -426,6 +427,7 @@ static int nfs_wait_schedule(void *word)
 	if (signal_pending(current))
 		return -ERESTARTSYS;
 	schedule();
+	try_to_freeze();
 	return 0;
 }
 
Index: linux-2.6/kernel/power/process.c
===================================================================
--- linux-2.6.orig/kernel/power/process.c
+++ linux-2.6/kernel/power/process.c
@@ -77,7 +77,9 @@ static void fake_signal_wake_up(struct t
 	unsigned long flags;
 
 	spin_lock_irqsave(&p->sighand->siglock, flags);
-	signal_wake_up(p, 0);
+	set_tsk_thread_flag(p, TIF_SIGPENDING);
+	if (!wake_up_state(p, TASK_INTERRUPTIBLE | TASK_KILLABLE))
+		kick_process(p);
 	spin_unlock_irqrestore(&p->sighand->siglock, flags);
 }
 
@@ -124,7 +126,7 @@ static bool freeze_task(struct task_stru
 	} else if (sig_only) {
 		return false;
 	} else {
-		wake_up_state(p, TASK_INTERRUPTIBLE);
+		wake_up_state(p, TASK_INTERRUPTIBLE | TASK_KILLABLE);
 	}
 
 	return true;

  parent reply	other threads:[~2008-05-06 22:07 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <200805070003.56387.rjw@sisk.pl>
2008-05-06 22:05 ` [RFC][PATCH 1/2] Freezer: Introduce PF_FREEZER_NOSIG Rafael J. Wysocki
2008-05-06 22:07 ` Rafael J. Wysocki [this message]
2008-05-07  9:41   ` [RFC][PATCH 2/2] Freezer: Try to handle killable tasks Pavel Machek
2008-05-07 13:53   ` Matthew Wilcox
     [not found]   ` <20080507094150.GG13858@elf.ucw.cz>
2008-05-07 13:57     ` Matthew Wilcox
     [not found]     ` <20080507135757.GT19219@parisc-linux.org>
2008-05-07 18:35       ` Rafael J. Wysocki
     [not found]   ` <20080507135333.GS19219@parisc-linux.org>
2008-05-07 18:41     ` Rafael J. Wysocki
     [not found]     ` <200805072041.20210.rjw@sisk.pl>
2008-05-19 22:59       ` Pavel Machek
     [not found] ` <200805070005.20403.rjw@sisk.pl>
2008-05-07  0:38   ` [RFC][PATCH 1/2] Freezer: Introduce PF_FREEZER_NOSIG Gautham R Shenoy
2008-05-07  9:36   ` Pavel Machek
     [not found]   ` <20080507003829.GA13608@in.ibm.com>
2008-05-07 12:11     ` Rafael J. Wysocki
     [not found]   ` <20080507093621.GF13858@elf.ucw.cz>
2008-05-07 12:16     ` Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200805070007.56998.rjw@sisk.pl \
    --to=rjw@sisk.pl \
    --cc=akpm@linux-foundation.org \
    --cc=clg@fr.ibm.com \
    --cc=howlett@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=matthew@wil.cx \
    --cc=menage@google.com \
    --cc=mingo@elte.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox