- patches.fixes/Freezer-sunrpc-NFS-dont-allow-TASK_KILLABLE-sleeps-to-block-the-freez...
[opensuse:kernel-source.git] / patches.fixes / Freezer-sunrpc-NFS-dont-allow-TASK_KILLABLE-sleeps-to-block-the-freezer.patch
1 From: Jeff Layton <jlayton@redhat.com>
2 Subject: Freezer / sunrpc / NFS: don't allow TASK_KILLABLE sleeps to block the freezer
3 Patch-mainline: Yes
4 Git-commit: d310310cbff18ec385c6ab4d58f33b100192a96a
5 References: bnc#775182
6
7 Allow the freezer to skip wait_on_bit_killable sleeps in the sunrpc
8 layer. This should allow suspend and hibernate events to proceed, even
9 when there are RPC's pending on the wire.
10
11 Also, wrap the TASK_KILLABLE sleeps in NFS layer in freezer_do_not_count
12 and freezer_count calls. This allows the freezer to skip tasks that are
13 sleeping while looping on EJUKEBOX or NFS4ERR_DELAY sorts of errors.
14
15 Signed-off-by: Jeff Layton <jlayton@redhat.com>
16 Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
17 Signed-off-by: Rafael J. Wysocki <rjw@suse.de>
18 ---
19  fs/nfs/inode.c          |    3 ++-
20  fs/nfs/nfs3proc.c       |    3 ++-
21  fs/nfs/nfs4proc.c       |    5 +++--
22  fs/nfs/proc.c           |    3 ++-
23  include/linux/freezer.h |   29 +++++++++++++++++++++++++++++
24  net/sunrpc/sched.c      |    3 ++-
25  6 files changed, 40 insertions(+), 6 deletions(-)
26
27
28 Index: linux-3.0-SLE11-SP2/fs/nfs/inode.c
29 ===================================================================
30 --- linux-3.0-SLE11-SP2.orig/fs/nfs/inode.c
31 +++ linux-3.0-SLE11-SP2/fs/nfs/inode.c
32 @@ -38,6 +38,7 @@
33  #include <linux/nfs_xdr.h>
34  #include <linux/slab.h>
35  #include <linux/compat.h>
36 +#include <linux/freezer.h>
37  
38  #include <asm/system.h>
39  #include <asm/uaccess.h>
40 @@ -77,7 +78,7 @@ int nfs_wait_bit_killable(void *word)
41  {
42         if (fatal_signal_pending(current))
43                 return -ERESTARTSYS;
44 -       schedule();
45 +       freezable_schedule();
46         return 0;
47  }
48  
49 Index: linux-3.0-SLE11-SP2/fs/nfs/nfs3proc.c
50 ===================================================================
51 --- linux-3.0-SLE11-SP2.orig/fs/nfs/nfs3proc.c
52 +++ linux-3.0-SLE11-SP2/fs/nfs/nfs3proc.c
53 @@ -17,6 +17,7 @@
54  #include <linux/nfs_page.h>
55  #include <linux/lockd/bind.h>
56  #include <linux/nfs_mount.h>
57 +#include <linux/freezer.h>
58  
59  #include "iostat.h"
60  #include "internal.h"
61 @@ -32,7 +33,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt,
62                 res = rpc_call_sync(clnt, msg, flags);
63                 if (res != -EJUKEBOX && res != -EKEYEXPIRED)
64                         break;
65 -               schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
66 +               freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
67                 res = -ERESTARTSYS;
68         } while (!fatal_signal_pending(current));
69         return res;
70 Index: linux-3.0-SLE11-SP2/fs/nfs/nfs4proc.c
71 ===================================================================
72 --- linux-3.0-SLE11-SP2.orig/fs/nfs/nfs4proc.c
73 +++ linux-3.0-SLE11-SP2/fs/nfs/nfs4proc.c
74 @@ -53,6 +53,7 @@
75  #include <linux/sunrpc/bc_xprt.h>
76  #include <linux/xattr.h>
77  #include <linux/utsname.h>
78 +#include <linux/freezer.h>
79  
80  #include "nfs4_fs.h"
81  #include "delegation.h"
82 @@ -242,7 +243,7 @@ static int nfs4_delay(struct rpc_clnt *c
83                 *timeout = NFS4_POLL_RETRY_MIN;
84         if (*timeout > NFS4_POLL_RETRY_MAX)
85                 *timeout = NFS4_POLL_RETRY_MAX;
86 -       schedule_timeout_killable(*timeout);
87 +       freezable_schedule_timeout_killable(*timeout);
88         if (fatal_signal_pending(current))
89                 res = -ERESTARTSYS;
90         *timeout <<= 1;
91 @@ -3992,7 +3993,7 @@ int nfs4_proc_delegreturn(struct inode *
92  static unsigned long
93  nfs4_set_lock_task_retry(unsigned long timeout)
94  {
95 -       schedule_timeout_killable(timeout);
96 +       freezable_schedule_timeout_killable(timeout);
97         timeout <<= 1;
98         if (timeout > NFS4_LOCK_MAXTIMEOUT)
99                 return NFS4_LOCK_MAXTIMEOUT;
100 Index: linux-3.0-SLE11-SP2/fs/nfs/proc.c
101 ===================================================================
102 --- linux-3.0-SLE11-SP2.orig/fs/nfs/proc.c
103 +++ linux-3.0-SLE11-SP2/fs/nfs/proc.c
104 @@ -41,6 +41,7 @@
105  #include <linux/nfs_fs.h>
106  #include <linux/nfs_page.h>
107  #include <linux/lockd/bind.h>
108 +#include <linux/freezer.h>
109  #include "internal.h"
110  
111  #define NFSDBG_FACILITY                NFSDBG_PROC
112 @@ -59,7 +60,7 @@ nfs_rpc_wrapper(struct rpc_clnt *clnt, s
113                 res = rpc_call_sync(clnt, msg, flags);
114                 if (res != -EKEYEXPIRED)
115                         break;
116 -               schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
117 +               freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
118                 res = -ERESTARTSYS;
119         } while (!fatal_signal_pending(current));
120         return res;
121 Index: linux-3.0-SLE11-SP2/include/linux/freezer.h
122 ===================================================================
123 --- linux-3.0-SLE11-SP2.orig/include/linux/freezer.h
124 +++ linux-3.0-SLE11-SP2/include/linux/freezer.h
125 @@ -117,6 +117,30 @@ static inline int freezer_should_skip(st
126  }
127  
128  /*
129 + * These macros are intended to be used whenever you want allow a task
130 + * that's sleeping in TASK_UNINTERRUPTIBLE or TASK_KILLABLE state to be frozen.
131 + * Note that neither return any clear indication of whether a freeze event
132 + * happened while in this function.
133 + */
134 +/* Like schedule(), but should not block the freezer. */
135 +#define freezable_schedule()                                           \
136 +({                                                                     \
137 +       freezer_do_not_count();                                         \
138 +       schedule();                                                     \
139 +       freezer_count();                                                \
140 +})
141 +
142 +/* Like schedule_timeout_killable(), but should not block the freezer. */
143 +#define freezable_schedule_timeout_killable(timeout)                   \
144 +({                                                                     \
145 +       long __retval;                                                  \
146 +       freezer_do_not_count();                                         \
147 +       __retval = schedule_timeout_killable(timeout);                  \
148 +       freezer_count();                                                \
149 +       __retval;                                                       \
150 +})
151 +
152 +/*
153   * Tell the freezer that the current task should be frozen by it
154   */
155  static inline void set_freezable(void)
156 @@ -182,6 +206,11 @@ static inline int freezer_should_skip(st
157  static inline void set_freezable(void) {}
158  static inline void set_freezable_with_signal(void) {}
159  
160 +#define freezable_schedule()  schedule()
161 +
162 +#define freezable_schedule_timeout_killable(timeout)                   \
163 +       schedule_timeout_killable(timeout)
164 +
165  #define wait_event_freezable(wq, condition)                            \
166                 wait_event_interruptible(wq, condition)
167  
168 Index: linux-3.0-SLE11-SP2/net/sunrpc/sched.c
169 ===================================================================
170 --- linux-3.0-SLE11-SP2.orig/net/sunrpc/sched.c
171 +++ linux-3.0-SLE11-SP2/net/sunrpc/sched.c
172 @@ -18,6 +18,7 @@
173  #include <linux/smp.h>
174  #include <linux/spinlock.h>
175  #include <linux/mutex.h>
176 +#include <linux/freezer.h>
177  
178  #include <linux/sunrpc/clnt.h>
179  
180 @@ -227,7 +228,7 @@ static int rpc_wait_bit_killable(void *w
181  {
182         if (fatal_signal_pending(current))
183                 return -ERESTARTSYS;
184 -       schedule();
185 +       freezable_schedule();
186         return 0;
187  }
188