From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753195AbcARA6d (ORCPT ); Sun, 17 Jan 2016 19:58:33 -0500 Received: from LGEAMRELO11.lge.com ([156.147.23.51]:39625 "EHLO lgeamrelo11.lge.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753022AbcARA6a (ORCPT ); Sun, 17 Jan 2016 19:58:30 -0500 X-Original-SENDERIP: 156.147.1.151 X-Original-MAILFROM: byungchul.park@lge.com X-Original-SENDERIP: 10.177.222.33 X-Original-MAILFROM: byungchul.park@lge.com From: Byungchul Park To: akpm@linux-foundation.org Cc: mingo@kernel.org, linux-kernel@vger.kernel.org, akinobu.mita@gmail.com, jack@suse.cz, torvalds@linux-foundation.org Subject: [PATCH v2] lib/spinlock_debug.c: prevent an infinite recursive cycle in spin_dump() Date: Mon, 18 Jan 2016 09:58:12 +0900 Message-Id: <1453078692-15291-1-git-send-email-byungchul.park@lge.com> X-Mailer: git-send-email 1.9.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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