From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757413AbcAaMcg (ORCPT ); Sun, 31 Jan 2016 07:32:36 -0500 Received: from mail-pf0-f195.google.com ([209.85.192.195]:36082 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757278AbcAaMce (ORCPT ); Sun, 31 Jan 2016 07:32:34 -0500 From: Sergey Senozhatsky X-Google-Original-From: Sergey Senozhatsky To: Peter Hurley Cc: Byungchul Park , akpm@linux-foundation.org, mingo@kernel.org, linux-kernel@vger.kernel.org, akinobu.mita@gmail.com, jack@suse.cz, torvalds@linux-foundation.org, Sergey Senozhatsky , Sergey Senozhatsky Subject: [PATCH 1/3] printk: introduce console_reset_on_panic() function Date: Sun, 31 Jan 2016 21:33:41 +0900 Message-Id: <1454243623-15109-1-git-send-email-sergey.senozhatsky@gmail.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <20160131123041.GA1306@swordfish> References: <20160131123041.GA1306@swordfish> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org CPU stop IPI issued from panic() on CPUA, can leave console_sem locked on CPUB if that cpu was holding the console_sem lock at the time when IPI arrived. console_flush_on_panic() is trying to workaround it by ignoring the return status of console_trylock() and unconditionally executing console_unlock(). console_unlock() has a dependency on at least one more lock - `logbuf_lock', which can be corrupted, for example, thus console_unlock() may not be able to print anything afterall. Introduce console_reset_on_panic() function to zap (re-init) printk locks and call this function from panic(). WARNING ======= This must be improved. console_reset_on_panic() is called before smp_send_stop(), so: a) we can have several CPU looping in console_unlock(), which is not so critical. b) we can re-init logbuf_lock while other CPU is holding it. Which is more serious and needs to fixed. The reason why console_reset_on_panic() is called this early is that panicing CPU does pr_emerg("Kernel panic...") and dump_stack() before it sends out smp_send_stop(). So if console_sem or logbug_lock, or some console device driver lock is/are corrupted then panic() may never smp_send_stop(). Not-Yet-Signed-off-by: Sergey Senozhatsky --- include/linux/console.h | 1 + kernel/panic.c | 1 + kernel/printk/printk.c | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/include/linux/console.h b/include/linux/console.h index ea731af..6edc2ea 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -151,6 +151,7 @@ extern void console_unlock(void); extern void console_conditional_schedule(void); extern void console_unblank(void); extern void console_flush_on_panic(void); +extern void console_reset_on_panic(void); extern struct tty_driver *console_device(int *); extern void console_stop(struct console *); extern void console_start(struct console *); diff --git a/kernel/panic.c b/kernel/panic.c index d96469d..71d43f6 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -119,6 +119,7 @@ void panic(const char *fmt, ...) console_verbose(); bust_spinlocks(1); + console_reset_on_panic(); va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 097ca8b..34642f7 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2394,6 +2394,11 @@ void console_flush_on_panic(void) console_unlock(); } +void console_reset_on_panic(void) +{ + zap_locks(); +} + /* * Return the console tty driver structure and its associated index */ -- 2.7.0