diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-12 17:46:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-12 17:46:33 -0500 |
commit | f01eb3640308c005d31b29d0a8bc2b7acb4e3f75 (patch) | |
tree | a4e249cc4b5880b841487c889c32be8b5414fd11 | |
parent | 6698e34720660e18b45e2e3b115ee4584d0c3b5e (diff) |
[BKL] add 'might_sleep()' to the outermost lock taker
As shown by the previous patch (6698e3472: "tty: Fix BKL taken under a
spinlock bug introduced in the BKL split") the BKL removal is prone to
some subtle issues, where removing the BKL in one place may in fact make
a previously nested BKL call the new outer call, and then prone to nasty
deadlocks with other spinlocks.
In general, we should never take the BKL while we're holding a spinlock,
so let's just add a "might_sleep()" to it (even though the BKL doesn't
technically sleep - at least not yet), and we'll get nice warnings the
next time this kind of problem happens during BKL removal.
Acked-and-Tested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | lib/kernel_lock.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c index 4ebfa5a164d7..5526b46aba94 100644 --- a/lib/kernel_lock.c +++ b/lib/kernel_lock.c | |||
@@ -122,8 +122,10 @@ void __lockfunc _lock_kernel(const char *func, const char *file, int line) | |||
122 | 122 | ||
123 | trace_lock_kernel(func, file, line); | 123 | trace_lock_kernel(func, file, line); |
124 | 124 | ||
125 | if (likely(!depth)) | 125 | if (likely(!depth)) { |
126 | might_sleep(); | ||
126 | __lock_kernel(); | 127 | __lock_kernel(); |
128 | } | ||
127 | current->lock_depth = depth; | 129 | current->lock_depth = depth; |
128 | } | 130 | } |
129 | 131 | ||