[kernel/f16] Add patch from Jeff Layton to fix suspend with NFS (rhbz #717735)
Josh Boyer
jwboyer at fedoraproject.org
Mon Dec 12 19:28:46 UTC 2011
commit 3a228cfea459b489ad387fa1a6953b0b84f2814c
Author: Josh Boyer <jwboyer at redhat.com>
Date: Thu Dec 8 10:14:55 2011 -0500
Add patch from Jeff Layton to fix suspend with NFS (rhbz #717735)
kernel.spec | 9 ++
nfs-client-freezer.patch | 299 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 308 insertions(+), 0 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 4357972..ba4599c 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -797,6 +797,9 @@ Patch21225: pci-Rework-ASPM-disable-code.patch
#rhbz #757839
Patch21230: net-sky2-88e8059-fix-link-speed.patch
+#rhbz 717735
+Patch21045: nfs-client-freezer.patch
+
%endif
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1465,6 +1468,9 @@ ApplyPatch pci-Rework-ASPM-disable-code.patch
#rhbz #757839
ApplyPatch net-sky2-88e8059-fix-link-speed.patch
+#rhbz 717735
+ApplyPatch nfs-client-freezer.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -2196,6 +2202,9 @@ fi
# and build.
%changelog
+* Mon Dec 12 2011 Josh Boyer <jwboyer at redhat.com>
+- Add patch from Jeff Layton to fix suspend with NFS (rhbz #717735)
+
* Fri Dec 09 2011 Josh Boyer <jwboyer at redhat.com> 3.1.5-1
- Linux 3.1.5
diff --git a/nfs-client-freezer.patch b/nfs-client-freezer.patch
new file mode 100644
index 0000000..6b4d34d
--- /dev/null
+++ b/nfs-client-freezer.patch
@@ -0,0 +1,299 @@
+@@ -, +, @@
+ fs/cifs/transport.c | 3 ++-
+ include/linux/freezer.h | 19 +++++++++++++++++--
+ 2 files changed, 19 insertions(+), 3 deletions(-)
+--- a/fs/cifs/transport.c
++++ a/fs/cifs/transport.c
+@@ -26,6 +26,7 @@
+ #include <linux/wait.h>
+ #include <linux/net.h>
+ #include <linux/delay.h>
++#include <linux/freezer.h>
+ #include <asm/uaccess.h>
+ #include <asm/processor.h>
+ #include <linux/mempool.h>
+@@ -324,7 +325,7 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
+ {
+ int error;
+
+- error = wait_event_killable(server->response_q,
++ error = wait_event_freezekillable(server->response_q,
+ midQ->midState != MID_REQUEST_SUBMITTED);
+ if (error < 0)
+ return -ERESTARTSYS;
+--- a/include/linux/freezer.h
++++ a/include/linux/freezer.h
+@@ -134,10 +134,25 @@ static inline void set_freezable_with_signal(void)
+ }
+
+ /*
+- * 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_killable() and wait_event_interruptible_timeout(), originally
++ * defined in <linux/wait.h>
+ */
+
++#define wait_event_freezekillable(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; \
++})
++
+ #define wait_event_freezable(wq, condition) \
+ ({ \
+ int __retval; \
+ include/linux/freezer.h | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+--- a/include/linux/freezer.h
++++ a/include/linux/freezer.h
+@@ -143,7 +143,7 @@ static inline void set_freezable_with_signal(void)
+ ({ \
+ int __retval; \
+ do { \
+- __retval = wait_event_killable(wq, \
++ __retval = wait_event_killable(wq, \
+ (condition) || freezing(current)); \
+ if (__retval && !freezing(current)) \
+ break; \
+ include/linux/freezer.h | 3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+--- a/include/linux/freezer.h
++++ a/include/linux/freezer.h
+@@ -203,6 +203,9 @@ static inline void set_freezable_with_signal(void) {}
+ #define wait_event_freezable_timeout(wq, condition, timeout) \
+ wait_event_interruptible_timeout(wq, condition, timeout)
+
++#define wait_event_freezekillable(wq, condition) \
++ wait_event_killable(wq, condition)
++
+ #endif /* !CONFIG_FREEZER */
+
+ #endif /* FREEZER_H_INCLUDED */
+ description on Rafael's request.]
+ include/linux/freezer.h | 11 +++--------
+ 1 files changed, 3 insertions(+), 8 deletions(-)
+--- a/include/linux/freezer.h
++++ a/include/linux/freezer.h
+@@ -142,14 +142,9 @@ static inline void set_freezable_with_signal(void)
+ #define wait_event_freezekillable(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()); \
++ freezer_do_not_count(); \
++ __retval = wait_event_killable(wq, (condition)); \
++ freezer_count(); \
+ __retval; \
+ })
+
+ fs/nfs/inode.c | 3 ++-
+ fs/nfs/nfs3proc.c | 3 ++-
+ fs/nfs/nfs4proc.c | 5 +++--
+ fs/nfs/proc.c | 3 ++-
+ include/linux/freezer.h | 28 ++++++++++++++++++++++++++++
+ net/sunrpc/sched.c | 3 ++-
+ 6 files changed, 39 insertions(+), 6 deletions(-)
+--- a/fs/nfs/inode.c
++++ a/fs/nfs/inode.c
+@@ -38,6 +38,7 @@
+ #include <linux/nfs_xdr.h>
+ #include <linux/slab.h>
+ #include <linux/compat.h>
++#include <linux/freezer.h>
+
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+@@ -77,7 +78,7 @@ int nfs_wait_bit_killable(void *word)
+ {
+ if (fatal_signal_pending(current))
+ return -ERESTARTSYS;
+- schedule();
++ freezable_schedule();
+ return 0;
+ }
+
+--- a/fs/nfs/nfs3proc.c
++++ a/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"
+@@ -32,7 +33,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
+ res = rpc_call_sync(clnt, msg, flags);
+ if (res != -EJUKEBOX && res != -EKEYEXPIRED)
+ break;
+- schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
++ freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
+ res = -ERESTARTSYS;
+ } while (!fatal_signal_pending(current));
+ return res;
+--- a/fs/nfs/nfs4proc.c
++++ a/fs/nfs/nfs4proc.c
+@@ -53,6 +53,7 @@
+ #include <linux/sunrpc/bc_xprt.h>
+ #include <linux/xattr.h>
+ #include <linux/utsname.h>
++#include <linux/freezer.h>
+
+ #include "nfs4_fs.h"
+ #include "delegation.h"
+@@ -244,7 +245,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
+ *timeout = NFS4_POLL_RETRY_MIN;
+ if (*timeout > NFS4_POLL_RETRY_MAX)
+ *timeout = NFS4_POLL_RETRY_MAX;
+- schedule_timeout_killable(*timeout);
++ freezable_schedule_timeout_killable(*timeout);
+ if (fatal_signal_pending(current))
+ res = -ERESTARTSYS;
+ *timeout <<= 1;
+@@ -3970,7 +3971,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4
+ static unsigned long
+ nfs4_set_lock_task_retry(unsigned long timeout)
+ {
+- schedule_timeout_killable(timeout);
++ freezable_schedule_timeout_killable(timeout);
+ timeout <<= 1;
+ if (timeout > NFS4_LOCK_MAXTIMEOUT)
+ return NFS4_LOCK_MAXTIMEOUT;
+--- a/fs/nfs/proc.c
++++ a/fs/nfs/proc.c
+@@ -41,6 +41,7 @@
+ #include <linux/nfs_fs.h>
+ #include <linux/nfs_page.h>
+ #include <linux/lockd/bind.h>
++#include <linux/freezer.h>
+ #include "internal.h"
+
+ #define NFSDBG_FACILITY NFSDBG_PROC
+@@ -59,7 +60,7 @@ nfs_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
+ res = rpc_call_sync(clnt, msg, flags);
+ if (res != -EKEYEXPIRED)
+ break;
+- schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
++ freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
+ res = -ERESTARTSYS;
+ } while (!fatal_signal_pending(current));
+ return res;
+--- a/include/linux/freezer.h
++++ a/include/linux/freezer.h
+@@ -134,6 +134,29 @@ static inline void set_freezable_with_signal(void)
+ }
+
+ /*
++ * These macros are intended to be used whenever you want allow a task that's
++ * sleeping in TASK_UNINTERRUPTIBLE or TASK_KILLABLE state to be frozen. Note
++ * that neither return any clear indication of whether a freeze event happened
++ * while in this function.
++ */
++
++/* Like schedule(), but should not block the freezer. */
++#define freezable_schedule() \
++({ \
++ freezer_do_not_count(); \
++ schedule(); \
++ freezer_count(); \
++})
++
++/* Like schedule_timeout_killable(), but should not block the freezer. */
++#define freezable_schedule_timeout_killable(timeout) \
++({ \
++ freezer_do_not_count(); \
++ schedule_timeout_killable(timeout); \
++ freezer_count(); \
++})
++
++/*
+ * Freezer-friendly wrappers around wait_event_interruptible(),
+ * wait_event_killable() and wait_event_interruptible_timeout(), originally
+ * defined in <linux/wait.h>
+@@ -192,6 +215,11 @@ static inline int freezer_should_skip(struct task_struct *p) { return 0; }
+ static inline void set_freezable(void) {}
+ static inline void set_freezable_with_signal(void) {}
+
++#define freezable_schedule() schedule()
++
++#define freezable_schedule_timeout_killable(timeout) \
++ schedule_timeout_killable(timeout)
++
+ #define wait_event_freezable(wq, condition) \
+ wait_event_interruptible(wq, condition)
+
+--- a/net/sunrpc/sched.c
++++ a/net/sunrpc/sched.c
+@@ -18,6 +18,7 @@
+ #include <linux/smp.h>
+ #include <linux/spinlock.h>
+ #include <linux/mutex.h>
++#include <linux/freezer.h>
+
+ #include <linux/sunrpc/clnt.h>
+
+@@ -231,7 +232,7 @@ static int rpc_wait_bit_killable(void *word)
+ {
+ if (fatal_signal_pending(current))
+ return -ERESTARTSYS;
+- schedule();
++ freezable_schedule();
+ return 0;
+ }
+
+ include/linux/freezer.h | 21 ++++++++++++++++++---
+ 1 files changed, 18 insertions(+), 3 deletions(-)
+--- a/include/linux/freezer.h
++++ a/include/linux/freezer.h
+@@ -140,18 +140,33 @@ static inline void set_freezable_with_signal(void)
+ * while in this function.
+ */
+
+-/* Like schedule(), but should not block the freezer. */
++/*
++ * Like schedule(), but should not block the freezer. It may return immediately
++ * if it ends up racing with the freezer. Callers must be able to deal with
++ * spurious wakeups.
++ */
+ #define freezable_schedule() \
+ ({ \
+ freezer_do_not_count(); \
+- schedule(); \
++ if (!try_to_freeze()) \
++ schedule(); \
+ freezer_count(); \
+ })
+
+-/* Like schedule_timeout_killable(), but should not block the freezer. */
++/*
++ * Like schedule_timeout_killable(), but should not block the freezer. It may
++ * end up returning immediately if it ends up racing with the freezer. Callers
++ * must be able to deal with the loose wakeup timing that can occur when the
++ * freezer races in. When that occurs, this function will return the timeout
++ * value instead of 0.
++ */
+ #define freezable_schedule_timeout_killable(timeout) \
+ ({ \
+ freezer_do_not_count(); \
++ if (try_to_freeze()) { \
++ freezer_count(); \
++ return timeout; \
++ } \
+ schedule_timeout_killable(timeout); \
+ freezer_count(); \
+ })
More information about the scm-commits
mailing list