aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/freezer.h
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2013-05-07 13:52:05 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-05-12 08:16:21 -0400
commit5853cc2a89f726e21d51ca0fd75757a03126a84b (patch)
tree7c5345de2310a387a951e12b07d04f4c5b295cb8 /include/linux/freezer.h
parent416ad3c9c0066405b83ec875b75496523549be09 (diff)
freezer: add unsafe versions of freezable helpers for CIFS
CIFS calls wait_event_freezekillable_unsafe with a VFS lock held, which is unsafe and will cause lockdep warnings when 6aa9707 "lockdep: check that no locks held at freeze time" is reapplied (it was reverted in dbf520a). CIFS shouldn't be doing this, but it has long-running syscalls that must hold a lock but also shouldn't block suspend. Until CIFS freeze handling is rewritten to use a signal to exit out of the critical section, add a new wait_event_freezekillable_unsafe helper that will not run the lockdep test when 6aa9707 is reapplied, and call it from CIFS. In practice the likley result of holding the lock while freezing is that a second task blocked on the lock will never freeze, aborting suspend, but it is possible to manufacture a case using the cgroup freezer, the lock, and the suspend freezer to create a deadlock. Silencing the lockdep warning here will allow problems to be found in other drivers that may have a more serious deadlock risk, and prevent new problems from being added. Acked-by: Pavel Machek <pavel@ucw.cz> Acked-by: Tejun Heo <tj@kernel.org> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Colin Cross <ccross@android.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'include/linux/freezer.h')
-rw-r--r--include/linux/freezer.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index 5b31e21c485f..d3c038ec9a88 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -212,6 +212,16 @@ static inline bool freezer_should_skip(struct task_struct *p)
212 __retval; \ 212 __retval; \
213}) 213})
214 214
215/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
216#define wait_event_freezekillable_unsafe(wq, condition) \
217({ \
218 int __retval; \
219 freezer_do_not_count(); \
220 __retval = wait_event_killable(wq, (condition)); \
221 freezer_count_unsafe(); \
222 __retval; \
223})
224
215#define wait_event_freezable(wq, condition) \ 225#define wait_event_freezable(wq, condition) \
216({ \ 226({ \
217 int __retval; \ 227 int __retval; \
@@ -277,6 +287,9 @@ static inline void set_freezable(void) {}
277#define wait_event_freezekillable(wq, condition) \ 287#define wait_event_freezekillable(wq, condition) \
278 wait_event_killable(wq, condition) 288 wait_event_killable(wq, condition)
279 289
290#define wait_event_freezekillable_unsafe(wq, condition) \
291 wait_event_killable(wq, condition)
292
280#endif /* !CONFIG_FREEZER */ 293#endif /* !CONFIG_FREEZER */
281 294
282#endif /* FREEZER_H_INCLUDED */ 295#endif /* FREEZER_H_INCLUDED */