Messages in this thread Patch in this message | | | From | Byungchul Park <> | Subject | [PATCH v2] lib/spinlock_debug.c: prevent an infinite recursive cycle in spin_dump() | Date | Mon, 18 Jan 2016 09:58:12 +0900 |
| |
It causes an infinite recursive cycle when using CONFIG_DEBUG_SPINLOCK, in the spin_dump(). Backtrace prints printk() -> console_trylock() -> do_raw_spin_lock() -> spint_bug() -> spin_dump() -> printk()... infinitely.
If the spin_bug() is called from a function like printk() which is trying to obtain the console lock, we should prevent the debug spinlock code from calling printk() again in that context.
Signed-off-by: Byungchul Park <byungchul.park@lge.com> --- kernel/locking/spinlock_debug.c | 11 +++++++++++ kernel/printk/printk.c | 5 +++++ 2 files changed, 16 insertions(+)
diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c index 0374a59..e745973 100644 --- a/kernel/locking/spinlock_debug.c +++ b/kernel/locking/spinlock_debug.c @@ -67,11 +67,22 @@ static void spin_dump(raw_spinlock_t *lock, const char *msg) dump_stack(); } +extern int is_console_lock(raw_spinlock_t *lock); + static void spin_bug(raw_spinlock_t *lock, const char *msg) { if (!debug_locks_off()) return; + /* + * If this function is called from a function like printk() + * which is trying to obtain the console lock, then we should + * not call printk() any more. Or it will cause an infinite + * recursive cycle! + */ + if (unlikely(is_console_lock(lock))) + return; + spin_dump(lock, msg); } diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 2ce8826..50ea552 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -119,6 +119,11 @@ static int __down_trylock_console_sem(unsigned long ip) up(&console_sem);\ } while (0) +int is_console_lock(raw_spinlock_t *lock) +{ + return &console_sem.lock == lock; +} + /* * This is used for debugging the mess that is the VT code by * keeping track if we have the console semaphore held. It's -- 1.9.1
| |