Received: by 10.223.176.46 with SMTP id f43csp1362152wra; Fri, 19 Jan 2018 10:23:22 -0800 (PST) X-Google-Smtp-Source: ACJfBos/S++5uDYLzJTAogiAZxvvQ+woeSHFLbekHMDuE+vZYvcitp1WXckvzTHp12mnEHguvWSX X-Received: by 10.98.36.77 with SMTP id r74mr25283288pfj.31.1516386202757; Fri, 19 Jan 2018 10:23:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516386202; cv=none; d=google.com; s=arc-20160816; b=qZHY1iAa5wVd2atkD6N0XDGGZZqxcpi5rZ4WR5Ba/7o4vD0R9xXS/i3Sl6TqCR5lha XUzIq3R6b4/heER6mKPKNIT5YGFz71g8uBVnbt55FvxmsC1LWeiLHB7DoLX9Qd424uNf n8fle4QjpT1whMFgjeuHYyY8rP8jNnIpqnHOldV/ipSpMA9htxeqkYAXzVD4198zxpp3 R0LH2jcrejGWK3rSHFeB0ZyKQdQExLMNY+oEODHnUZphlBfagRECRhRTsW5OG2JUSacp mZ2+sueAldQ8YRy5gJqQ7IHyVlIhxtnRWgRKVtV3tFYP4laQDlQiBS5YkEoAMgzL7+tc 8shA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:cc:to:from:date :dmarc-filter:arc-authentication-results; bh=Z9Lvbp/JE2lEszl7NO0rIVRERz7SkhwkfSDeB9ISj+I=; b=FYGEntlwLZqtYdkI/y/XbRQKGMklXYGTmSBFqtlP6W4ShxNYFbaBlrD3dmOwjgh9G2 2nm/TP1ojSLP7mRObshrBH1G0VT7w/gui5ZfywjX09pNnFvTeJ/+Jd7WbJZynkRA7dZO LyXUg00VPVcouhCDh/Zj1SHblG6zxs+sRE24AYOlD2fizYV3INWAsJfgqKvOMCxVUIWU 1GwhBS8j6kxS5p6ucmPR+165KbYzwDnC8dJKwgpdgy6ZPwk4Wi956rY1ZT1smgb/kGbF nGyDw3s6fZHD/91nbCuwCBWtLU5v0bIx8MEVtBUbN4hYxqe/JjfzlCPqjGnFW7odFOk3 ieNA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u79si5288593pfi.315.2018.01.19.10.23.08; Fri, 19 Jan 2018 10:23:22 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932393AbeASSVC (ORCPT + 99 others); Fri, 19 Jan 2018 13:21:02 -0500 Received: from mail.kernel.org ([198.145.29.99]:49820 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755809AbeASSU4 (ORCPT ); Fri, 19 Jan 2018 13:20:56 -0500 Received: from gandalf.local.home (cpe-172-100-180-131.stny.res.rr.com [172.100.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6FD9020C0F; Fri, 19 Jan 2018 18:20:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6FD9020C0F Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=goodmis.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=rostedt@goodmis.org Date: Fri, 19 Jan 2018 13:20:52 -0500 From: Steven Rostedt To: Tejun Heo Cc: Petr Mladek , Sergey Senozhatsky , Sergey Senozhatsky , akpm@linux-foundation.org, linux-mm@kvack.org, Cong Wang , Dave Hansen , Johannes Weiner , Mel Gorman , Michal Hocko , Vlastimil Babka , Peter Zijlstra , Linus Torvalds , Jan Kara , Mathieu Desnoyers , Tetsuo Handa , rostedt@home.goodmis.org, Byungchul Park , Pavel Machek , linux-kernel@vger.kernel.org Subject: Re: [PATCH v5 0/2] printk: Console owner and waiter logic cleanup Message-ID: <20180119132052.02b89626@gandalf.local.home> In-Reply-To: <20180117134201.0a9cbbbf@gandalf.local.home> References: <20180110140547.GZ3668920@devbig577.frc2.facebook.com> <20180110130517.6ff91716@vmware.local.home> <20180111045817.GA494@jagdpanzerIV> <20180111093435.GA24497@linux.suse> <20180111103845.GB477@jagdpanzerIV> <20180111112908.50de440a@vmware.local.home> <20180111203057.5b1a8f8f@gandalf.local.home> <20180111215547.2f66a23a@gandalf.local.home> <20180116194456.GS3460072@devbig577.frc2.facebook.com> <20180117091208.ezvuhumnsarz5thh@pathway.suse.cz> <20180117151509.GT3460072@devbig577.frc2.facebook.com> <20180117121251.7283a56e@gandalf.local.home> <20180117134201.0a9cbbbf@gandalf.local.home> X-Mailer: Claws Mail 3.14.0 (GTK+ 2.24.31; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Tejun, I was thinking about this a bit more, and instead of offloading a recursive printk, perhaps its best to simply throttle it. Because the problem may not go away if a printk thread takes over, because the bug is really the printk infrastructure filling the printk buffer keeping printk from ever stopping. This patch detects that printk is causing itself to print more and throttles it after 3 messages have printed due to recursion. Could you see if this helps your test cases? I built this on top of linux-next (yesterday's branch). It compiles and boots, but I didn't do any other tests on it. Thanks! -- Steve diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 9cb943c90d98..2c7f18876224 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1826,6 +1826,75 @@ static size_t log_output(int facility, int level, enum log_flags lflags, const c /* Store it in the record log */ return log_store(facility, level, lflags, 0, dict, dictlen, text, text_len); } +/* + * Used for which context the printk is in. + * NMI = 0 + * IRQ = 1 + * SOFTIRQ = 2 + * NORMAL = 3 + * + * Stack ordered, where the lower number can preempt + * the higher number: mask &= mask - 1, will only clear + * the lowerest set bit. + */ +enum { + CTX_NMI, + CTX_IRQ, + CTX_SOFTIRQ, + CTX_NORMAL, +}; + +static DEFINE_PER_CPU(int, recursion_bits); +static DEFINE_PER_CPU(int, recursion_count); +static atomic_t recursion_overflow; +static const int recursion_max = 3; + +static int __recursion_check_test(int val) +{ + unsigned long pc = preempt_count(); + int bit; + + if (!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET))) + bit = CTX_NORMAL; + else + bit = pc & NMI_MASK ? CTX_NMI : + pc & HARDIRQ_MASK ? CTX_IRQ : CTX_SOFTIRQ; + + return val & (1 << bit); +} + +static bool recursion_check_test(void) +{ + int val = this_cpu_read(recursion_bits); + + return __recursion_check_test(val); +} + +static bool recursion_check_start(void) +{ + int val = this_cpu_read(recursion_bits); + int set; + + set = __recursion_check_test(val); + + if (unlikely(set)) + return true; + + val |= set; + this_cpu_write(recursion_bits, val); + return false; +} + +static void recursion_check_finish(bool recursion) +{ + int val = this_cpu_read(recursion_bits); + + if (recursion) + return; + + val &= val - 1; + this_cpu_write(recursion_bits, val); +} asmlinkage int vprintk_emit(int facility, int level, const char *dict, size_t dictlen, @@ -1849,6 +1918,17 @@ asmlinkage int vprintk_emit(int facility, int level, /* This stops the holder of console_sem just where we want him */ logbuf_lock_irqsave(flags); + + if (recursion_check_test()) { + /* A printk happened within a printk at the same context */ + if (this_cpu_inc_return(recursion_count) > recursion_max) { + atomic_inc(&recursion_overflow); + logbuf_unlock_irqrestore(flags); + printed_len = 0; + goto out; + } + } + /* * The printf needs to come first; we need the syslog * prefix which might be passed-in as a parameter. @@ -1895,12 +1975,14 @@ asmlinkage int vprintk_emit(int facility, int level, /* If called from the scheduler, we can not call up(). */ if (!in_sched) { + bool recursion; /* * Disable preemption to avoid being preempted while holding * console_sem which would prevent anyone from printing to * console */ preempt_disable(); + recursion = recursion_check_start(); /* * Try to acquire and then immediately release the console * semaphore. The release will print out buffers and wake up @@ -1908,9 +1990,12 @@ asmlinkage int vprintk_emit(int facility, int level, */ if (console_trylock_spinning()) console_unlock(); + + recursion_check_finish(recursion); + this_cpu_write(recursion_count, 0); preempt_enable(); } - +out: return printed_len; } EXPORT_SYMBOL(vprintk_emit); @@ -2343,9 +2428,14 @@ void console_unlock(void) seen_seq = log_next_seq; } - if (console_seq < log_first_seq) { + if (console_seq < log_first_seq || atomic_read(&recursion_overflow)) { + size_t missed; + + missed = atomic_xchg(&recursion_overflow, 0); + missed += log_first_seq - console_seq; + len = sprintf(text, "** %u printk messages dropped **\n", - (unsigned)(log_first_seq - console_seq)); + (unsigned)missed); /* messages are gone, move to first one */ console_seq = log_first_seq;