From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965175AbcCNOQS (ORCPT ); Mon, 14 Mar 2016 10:16:18 -0400 Received: from mail-pa0-f47.google.com ([209.85.220.47]:34326 "EHLO mail-pa0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964985AbcCNOQK (ORCPT ); Mon, 14 Mar 2016 10:16:10 -0400 From: Sergey Senozhatsky To: Andrew Morton Cc: Jan Kara , Petr Mladek , Tejun Heo , Tetsuo Handa , linux-kernel@vger.kernel.org, Byungchul Park , Sergey Senozhatsky , Sergey Senozhatsky , Jan Kara Subject: [RFC][PATCH v4 2/2] printk: Skip messages on oops Date: Mon, 14 Mar 2016 23:13:40 +0900 Message-Id: <1457964820-4642-3-git-send-email-sergey.senozhatsky@gmail.com> X-Mailer: git-send-email 2.8.0.rc0 In-Reply-To: <1457964820-4642-1-git-send-email-sergey.senozhatsky@gmail.com> References: <1457964820-4642-1-git-send-email-sergey.senozhatsky@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jan Kara When there are too many messages in the kernel printk buffer it can take very long to print them to console (especially when using slow serial console). This is undesirable during oops so when we encounter oops and there are more than 100 messages to print, print just the newest 100 messages and then the oops message. [ss: fix tiny config build] Signed-off-by: Jan Kara Signed-off-by: Sergey Senozhatsky --- kernel/printk/printk.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 3c4f8b7..cb15c7b 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -268,6 +268,9 @@ static u64 console_seq; static u32 console_idx; static enum log_flags console_prev; +/* current record sequence when oops happened */ +static u64 oops_start_seq; + /* the next printk record to read after the last 'clear' command */ static u64 clear_seq; static u32 clear_idx; @@ -1771,6 +1774,9 @@ asmlinkage int vprintk_emit(int facility, int level, strlen(recursion_msg)); } + if (oops_in_progress && !oops_start_seq) + oops_start_seq = log_next_seq; + /* * The printf needs to come first; we need the syslog * prefix which might be passed-in as a parameter. @@ -2006,6 +2012,7 @@ static u64 syslog_seq; static u32 syslog_idx; static u64 console_seq; static u32 console_idx; +static u64 oops_start_seq; static enum log_flags syslog_prev; static u64 log_first_seq; static u32 log_first_idx; @@ -2331,6 +2338,12 @@ out: raw_spin_unlock_irqrestore(&logbuf_lock, flags); } +/* + * When oops happens and there are more messages to be printed in the printk + * buffer that this, skip some mesages and print only this many newest messages. + */ +#define PRINT_MSGS_BEFORE_OOPS 100 + /** * console_unlock - unlock the console system * @@ -2399,7 +2412,28 @@ again: seen_seq = log_next_seq; } - if (console_seq < log_first_seq) { + /* + * If oops happened and there are more than + * PRINT_MSGS_BEFORE_OOPS messages pending before oops message, + * skip them to make oops appear faster. + */ + if (oops_start_seq && + console_seq + PRINT_MSGS_BEFORE_OOPS < oops_start_seq) { + len = sprintf(text, + "** %u printk messages dropped due to oops ** ", + (unsigned)(oops_start_seq - console_seq - + PRINT_MSGS_BEFORE_OOPS)); + if (console_seq < log_first_seq) { + console_seq = log_first_seq; + console_idx = log_first_idx; + } + while (console_seq < + oops_start_seq - PRINT_MSGS_BEFORE_OOPS) { + console_idx = log_next(console_idx); + console_seq++; + } + console_prev = 0; + } else if (console_seq < log_first_seq) { len = sprintf(text, "** %u printk messages dropped ** ", (unsigned)(log_first_seq - console_seq)); -- 2.8.0.rc0