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;
next prev 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