diff options
-rw-r--r-- | fs/nfs/inode.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs3proc.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 4 | ||||
-rw-r--r-- | include/linux/freezer.h | 42 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 2 |
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 | } |
85 | EXPORT_SYMBOL_GPL(nfs_wait_bit_killable); | 85 | EXPORT_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 | |||
4528 | static unsigned long | 4528 | static unsigned long |
4529 | nfs4_set_lock_task_retry(unsigned long timeout) | 4529 | nfs4_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); | |||
46 | extern void thaw_processes(void); | 46 | extern void thaw_processes(void); |
47 | extern void thaw_kernel_threads(void); | 47 | extern void thaw_kernel_threads(void); |
48 | 48 | ||
49 | static 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 | */ | ||
53 | static 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 | ||
61 | static inline bool try_to_freeze(void) | ||
62 | { | ||
63 | return try_to_freeze_unsafe(); | ||
64 | } | ||
65 | |||
57 | extern bool freeze_task(struct task_struct *p); | 66 | extern bool freeze_task(struct task_struct *p); |
58 | extern bool set_freezable(void); | 67 | extern 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 */ | ||
128 | static 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 | ||