aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/nfs/nfs3proc.c2
-rw-r--r--fs/nfs/nfs4proc.c4
-rw-r--r--include/linux/freezer.h42
-rw-r--r--net/sunrpc/sched.c2
5 files changed, 46 insertions, 6 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index c1c7a9d78722..ce727047ee87 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -79,7 +79,7 @@ int nfs_wait_bit_killable(void *word)
79{ 79{
80 if (fatal_signal_pending(current)) 80 if (fatal_signal_pending(current))
81 return -ERESTARTSYS; 81 return -ERESTARTSYS;
82 freezable_schedule(); 82 freezable_schedule_unsafe();
83 return 0; 83 return 0;
84} 84}
85EXPORT_SYMBOL_GPL(nfs_wait_bit_killable); 85EXPORT_SYMBOL_GPL(nfs_wait_bit_killable);
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 43ea96ced28c..ce90eb4775c2 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -33,7 +33,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
33 res = rpc_call_sync(clnt, msg, flags); 33 res = rpc_call_sync(clnt, msg, flags);
34 if (res != -EJUKEBOX) 34 if (res != -EJUKEBOX)
35 break; 35 break;
36 freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME); 36 freezable_schedule_timeout_killable_unsafe(NFS_JUKEBOX_RETRY_TIME);
37 res = -ERESTARTSYS; 37 res = -ERESTARTSYS;
38 } while (!fatal_signal_pending(current)); 38 } while (!fatal_signal_pending(current));
39 return res; 39 return res;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 8fbc10054115..9b18af167815 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -268,7 +268,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
268 *timeout = NFS4_POLL_RETRY_MIN; 268 *timeout = NFS4_POLL_RETRY_MIN;
269 if (*timeout > NFS4_POLL_RETRY_MAX) 269 if (*timeout > NFS4_POLL_RETRY_MAX)
270 *timeout = NFS4_POLL_RETRY_MAX; 270 *timeout = NFS4_POLL_RETRY_MAX;
271 freezable_schedule_timeout_killable(*timeout); 271 freezable_schedule_timeout_killable_unsafe(*timeout);
272 if (fatal_signal_pending(current)) 272 if (fatal_signal_pending(current))
273 res = -ERESTARTSYS; 273 res = -ERESTARTSYS;
274 *timeout <<= 1; 274 *timeout <<= 1;
@@ -4528,7 +4528,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4
4528static unsigned long 4528static unsigned long
4529nfs4_set_lock_task_retry(unsigned long timeout) 4529nfs4_set_lock_task_retry(unsigned long timeout)
4530{ 4530{
4531 freezable_schedule_timeout_killable(timeout); 4531 freezable_schedule_timeout_killable_unsafe(timeout);
4532 timeout <<= 1; 4532 timeout <<= 1;
4533 if (timeout > NFS4_LOCK_MAXTIMEOUT) 4533 if (timeout > NFS4_LOCK_MAXTIMEOUT)
4534 return NFS4_LOCK_MAXTIMEOUT; 4534 return NFS4_LOCK_MAXTIMEOUT;
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index e70df40d84f6..5b31e21c485f 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -46,7 +46,11 @@ extern int freeze_kernel_threads(void);
46extern void thaw_processes(void); 46extern void thaw_processes(void);
47extern void thaw_kernel_threads(void); 47extern void thaw_kernel_threads(void);
48 48
49static inline bool try_to_freeze(void) 49/*
50 * DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION
51 * If try_to_freeze causes a lockdep warning it means the caller may deadlock
52 */
53static inline bool try_to_freeze_unsafe(void)
50{ 54{
51 might_sleep(); 55 might_sleep();
52 if (likely(!freezing(current))) 56 if (likely(!freezing(current)))
@@ -54,6 +58,11 @@ static inline bool try_to_freeze(void)
54 return __refrigerator(false); 58 return __refrigerator(false);
55} 59}
56 60
61static inline bool try_to_freeze(void)
62{
63 return try_to_freeze_unsafe();
64}
65
57extern bool freeze_task(struct task_struct *p); 66extern bool freeze_task(struct task_struct *p);
58extern bool set_freezable(void); 67extern bool set_freezable(void);
59 68
@@ -115,6 +124,14 @@ static inline void freezer_count(void)
115 try_to_freeze(); 124 try_to_freeze();
116} 125}
117 126
127/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
128static inline void freezer_count_unsafe(void)
129{
130 current->flags &= ~PF_FREEZER_SKIP;
131 smp_mb();
132 try_to_freeze_unsafe();
133}
134
118/** 135/**
119 * freezer_should_skip - whether to skip a task when determining frozen 136 * freezer_should_skip - whether to skip a task when determining frozen
120 * state is reached 137 * state is reached
@@ -152,6 +169,14 @@ static inline bool freezer_should_skip(struct task_struct *p)
152 freezer_count(); \ 169 freezer_count(); \
153}) 170})
154 171
172/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
173#define freezable_schedule_unsafe() \
174({ \
175 freezer_do_not_count(); \
176 schedule(); \
177 freezer_count_unsafe(); \
178})
179
155/* Like schedule_timeout_killable(), but should not block the freezer. */ 180/* Like schedule_timeout_killable(), but should not block the freezer. */
156#define freezable_schedule_timeout_killable(timeout) \ 181#define freezable_schedule_timeout_killable(timeout) \
157({ \ 182({ \
@@ -162,6 +187,16 @@ static inline bool freezer_should_skip(struct task_struct *p)
162 __retval; \ 187 __retval; \
163}) 188})
164 189
190/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
191#define freezable_schedule_timeout_killable_unsafe(timeout) \
192({ \
193 long __retval; \
194 freezer_do_not_count(); \
195 __retval = schedule_timeout_killable(timeout); \
196 freezer_count_unsafe(); \
197 __retval; \
198})
199
165/* 200/*
166 * Freezer-friendly wrappers around wait_event_interruptible(), 201 * Freezer-friendly wrappers around wait_event_interruptible(),
167 * wait_event_killable() and wait_event_interruptible_timeout(), originally 202 * wait_event_killable() and wait_event_interruptible_timeout(), originally
@@ -225,9 +260,14 @@ static inline void set_freezable(void) {}
225 260
226#define freezable_schedule() schedule() 261#define freezable_schedule() schedule()
227 262
263#define freezable_schedule_unsafe() schedule()
264
228#define freezable_schedule_timeout_killable(timeout) \ 265#define freezable_schedule_timeout_killable(timeout) \
229 schedule_timeout_killable(timeout) 266 schedule_timeout_killable(timeout)
230 267
268#define freezable_schedule_timeout_killable_unsafe(timeout) \
269 schedule_timeout_killable(timeout)
270
231#define wait_event_freezable(wq, condition) \ 271#define wait_event_freezable(wq, condition) \
232 wait_event_interruptible(wq, condition) 272 wait_event_interruptible(wq, condition)
233 273
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index f8529fc8e542..8dcfadcef5d3 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -254,7 +254,7 @@ static int rpc_wait_bit_killable(void *word)
254{ 254{
255 if (fatal_signal_pending(current)) 255 if (fatal_signal_pending(current))
256 return -ERESTARTSYS; 256 return -ERESTARTSYS;
257 freezable_schedule(); 257 freezable_schedule_unsafe();
258 return 0; 258 return 0;
259} 259}
260 260