Received: by 10.223.176.46 with SMTP id f43csp3807608wra; Mon, 22 Jan 2018 22:41:38 -0800 (PST) X-Google-Smtp-Source: AH8x227a4LClBPV51gd5VrDcWs/G1lUXWZ9n3Noz8Fu+3mdx+Ngf2DAm+WyB0nQWPwCRL6wNPafl X-Received: by 2002:a17:902:8a4:: with SMTP id 33-v6mr2337613pll.279.1516689698814; Mon, 22 Jan 2018 22:41:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516689698; cv=none; d=google.com; s=arc-20160816; b=uOAtmu+lb7xUSrOoUfzDUKi7/GIORcydFYZtz5WWsiAXdOVwLbF2J845th4YcT4Phu VL0CvGgSZ36Fz3Ogm6UbT6IdB38PGxv2Sar8aHQjzaeSCrc3912OyYZ6mtUk7PwYV5EA /Xf5izSYY6EEnGXnfas0qWtYfYKPHn4/sIgnBW0uBsbARCUnUwvr6PHLtxVlWIXOxEip bBM41Qq68c8ZSjZk2OgCzpR3ZEymC+3eJMrKXTDrm7Go6p7QykjKJQjZOSPWK8v6eOiR ssXHwy+YNWAVtNJHDwK61tznRPbT18cpLUQJAQyOTUrEWgAj8IA82edqLuDpiLqIhOKU uhHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature:arc-authentication-results; bh=uePZNpWiCRbXLljAvCKyY21IJ09evjRJv6EbwjslW9s=; b=bxhTbeZU6RTZ2n/c3Nrv/YsTjuL7dsdhg+sxk8nSiGiaN0KOgDPu82+vMpDeAI/l2v L2vadpSkHwshZe8XeEbDFQJK36z7ILKCXeUibQZNrIvSRUhMvu1hqGFzAp77N6dWm9Cz QjD1mEmElfDY6P+81+ERGWaTRq+A0U4Hrl/qzfS08A4b7Eh8JvaotxNXRS1xZ+r2LRrL 4+guRohASrPDUa0ne6S3SgeuOoxdxpRj5P4ivhFsrSEYgMT6i0uDhtgzsEQ28XOZLhjG mtC7sNmbn6MlLqfIAfPWr/t6Ffx91cvsxQeuZ4dDLQ/Vwxr/2KH0kW7ISCSQe29Q85Cl l0RA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=hQfWQgRh; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v15-v6si4227450ply.781.2018.01.22.22.41.25; Mon, 22 Jan 2018 22:41:38 -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; dkim=pass header.i=@gmail.com header.s=20161025 header.b=hQfWQgRh; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751487AbeAWGkb (ORCPT + 99 others); Tue, 23 Jan 2018 01:40:31 -0500 Received: from mail-pg0-f68.google.com ([74.125.83.68]:37723 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751314AbeAWGk3 (ORCPT ); Tue, 23 Jan 2018 01:40:29 -0500 Received: by mail-pg0-f68.google.com with SMTP id z17so9015634pgc.4 for ; Mon, 22 Jan 2018 22:40:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=uePZNpWiCRbXLljAvCKyY21IJ09evjRJv6EbwjslW9s=; b=hQfWQgRhh7EeIi8KL1Bwh3aeaiR47sNBdTMl/Ijnk1Mht9jOxrEM1GvWnx8GyCZjn6 6rlt5AIZaYDj/keX1XQXBRhp5z2Ibk4I+fJA11PaEbymKc6KlzaQq4+S3GXzFC12W0Im iNPBEpUiKMMhK5q15xkDg5h8NNjxbJP7apETGeaz2+s9TbTZGI6q0p/3/th/SgoY9ohj NaGdNF7rGPBwO5n+TO0yPfPloH4ikpvAFF/MqUv8S+4M1UhtKOI01mIXj8yMsTVitVJo rLCRESfCwBVehhM5Xi/CauzwCvmFYf1Nfxprvmk6Q/Pq3tESYz0tDjJFkyEaXmGTBPRf ICwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=uePZNpWiCRbXLljAvCKyY21IJ09evjRJv6EbwjslW9s=; b=I0iB6r7mTe3369OkmLCMrgNJVNQJFP22euIuEiPatvnScDMKMCxJsyo64VFgcRWA9u uUtaPOshQC09Z1++ICTXW3eyNmn8gDx9TrdFyXXm2N87ZmYdXGQZojitu/Dv4xKS4ErX 6w2VghRwowUBzRBvkZJekV+qT/LgcAqyGRR9ioIo8iJy7yY2RB7V8vmCrd3G+uEaWus5 9v6+PYnOpJz5wFhhBOeUEtA5Z2bvlMROrFdPKMrXCGhAvTTeJdisQAwowCJofh1+gOel jYIp1xV8SsiJ/r4nH9/jfHv1Z5NzGdB4l2zKLQ1SD0mRkkqowzvuzsK1GJIQUXKYz1v0 oiTA== X-Gm-Message-State: AKwxytcjWLevH80dI96oGMtufBfjHrEI2NW1ywyLiKsOuNfTksSqIPnO EshnmWq6XzNawGi/Bgv3d4U= X-Received: by 2002:a17:902:868f:: with SMTP id g15-v6mr2140213plo.137.1516689628629; Mon, 22 Jan 2018 22:40:28 -0800 (PST) Received: from localhost ([39.7.50.209]) by smtp.gmail.com with ESMTPSA id f7sm4960403pgq.31.2018.01.22.22.40.26 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 22 Jan 2018 22:40:27 -0800 (PST) Date: Tue, 23 Jan 2018 15:40:23 +0900 From: Sergey Senozhatsky To: Petr Mladek , Tejun Heo , Steven Rostedt Cc: 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, Sergey Senozhatsky Subject: Re: [PATCH v5 0/2] printk: Console owner and waiter logic cleanup Message-ID: <20180123064023.GA492@jagdpanzerIV> References: <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> <20180119132052.02b89626@gandalf.local.home> <20180120071402.GB8371@jagdpanzerIV> <20180120104931.1942483e@gandalf.local.home> <20180121141521.GA429@tigerII.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180121141521.GA429@tigerII.localdomain> User-Agent: Mutt/1.9.2 (2017-12-15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hello, On (01/21/18 23:15), Sergey Senozhatsky wrote: [..] > we have printk recursion from console drivers. it's redirected to > printk_safe and we queue an IRQ work to flush the buffer > > printk > console_unlock > call_console_drivers > net_console > printk > printk_save -> irq_work queue > > now console_unlock() enables local IRQs, we have the printk_safe > flush. but printk_safe flush does not call into the console_unlock(), > it uses printk_deferred() version of printk > > IRQ work > > prink_safe_flush > printk_deferred -> irq_work queue > > > so we schedule another IRQ work (deferred printk work), which eventually > tries to lock console_sem > > IRQ work > wake_up_klogd_work_func() > if (console_trylock()) > console_unlock() Why do we even use irq_work for printk_safe? Okay... So, how about this. For printk_safe we use system_wq for flushing. IOW, we flush from a task running exactly on the same CPU which hit printk recursion, not from IRQ. From vprintk_safe() recursion, we queue work on *that* CPU. Which gives us the following thing: if CPU stuck in console_unlock() loop with preemption disabled, then system_wq does not schedule on that CPU and we, thus, don't flush printk_safe buffer from that CPU. But if CPU can reschedule, then we are kinda OK to flush printk_safe buffer, printing extra messages from that CPU will not lock it up, because it's in preemptible context. Thoughts? Something like this: From: Sergey Senozhatsky Subject: [PATCH] printk/safe: use slowpath flush for printk_safe --- kernel/printk/printk_safe.c | 53 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c index 3e3c2004bb23..c641853a5fa9 100644 --- a/kernel/printk/printk_safe.c +++ b/kernel/printk/printk_safe.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "internal.h" @@ -50,6 +52,7 @@ struct printk_safe_seq_buf { atomic_t len; /* length of written data */ atomic_t message_lost; struct irq_work work; /* IRQ work that flushes the buffer */ + struct work_struct slowpath_flush_work; unsigned char buffer[SAFE_LOG_BUF_LEN]; }; @@ -61,12 +64,20 @@ static DEFINE_PER_CPU(struct printk_safe_seq_buf, nmi_print_seq); #endif /* Get flushed in a more safe context. */ -static void queue_flush_work(struct printk_safe_seq_buf *s) +static void queue_irq_flush_work(struct printk_safe_seq_buf *s) { if (printk_safe_irq_ready) irq_work_queue(&s->work); } +static void queue_slowpath_flush_work(struct printk_safe_seq_buf *s) +{ + if (printk_safe_irq_ready) + queue_work_on(smp_processor_id(), + system_wq, + &s->slowpath_flush_work); +} + /* * Add a message to per-CPU context-dependent buffer. NMI and printk-safe * have dedicated buffers, because otherwise printk-safe preempted by @@ -89,7 +100,7 @@ static __printf(2, 0) int printk_safe_log_store(struct printk_safe_seq_buf *s, /* The trailing '\0' is not counted into len. */ if (len >= sizeof(s->buffer) - 1) { atomic_inc(&s->message_lost); - queue_flush_work(s); + queue_irq_flush_work(s); return 0; } @@ -112,7 +123,6 @@ static __printf(2, 0) int printk_safe_log_store(struct printk_safe_seq_buf *s, if (atomic_cmpxchg(&s->len, len, len + add) != len) goto again; - queue_flush_work(s); return add; } @@ -243,6 +253,35 @@ static void __printk_safe_flush(struct irq_work *work) raw_spin_unlock_irqrestore(&read_lock, flags); } +/* NMI buffers are always flushed */ +static void flush_nmi_buffer(struct irq_work *work) +{ + __printk_safe_flush(work); +} + +/* printk_safe buffers flushing, on the contrary, can be postponed */ +static void flush_printk_safe_buffer(struct irq_work *work) +{ + struct printk_safe_seq_buf *s = + container_of(work, struct printk_safe_seq_buf, work); + + if (is_console_locked()) { + queue_slowpath_flush_work(s); + return; + } + + __printk_safe_flush(work); +} + +static void slowpath_flush_work_fn(struct work_struct *work) +{ + struct printk_safe_seq_buf *s = + container_of(work, struct printk_safe_seq_buf, + slowpath_flush_work); + + __printk_safe_flush(&s->work); +} + /** * printk_safe_flush - flush all per-cpu nmi buffers. * @@ -300,6 +339,7 @@ static __printf(1, 0) int vprintk_nmi(const char *fmt, va_list args) { struct printk_safe_seq_buf *s = this_cpu_ptr(&nmi_print_seq); + queue_irq_flush_work(s); return printk_safe_log_store(s, fmt, args); } @@ -343,6 +383,7 @@ static __printf(1, 0) int vprintk_safe(const char *fmt, va_list args) { struct printk_safe_seq_buf *s = this_cpu_ptr(&safe_print_seq); + queue_slowpath_flush_work(s); return printk_safe_log_store(s, fmt, args); } @@ -387,11 +428,13 @@ void __init printk_safe_init(void) struct printk_safe_seq_buf *s; s = &per_cpu(safe_print_seq, cpu); - init_irq_work(&s->work, __printk_safe_flush); + init_irq_work(&s->work, flush_printk_safe_buffer); + INIT_WORK(&s->slowpath_flush_work, slowpath_flush_work_fn); #ifdef CONFIG_PRINTK_NMI s = &per_cpu(nmi_print_seq, cpu); - init_irq_work(&s->work, __printk_safe_flush); + init_irq_work(&s->work, flush_nmi_buffer); + /* we don't use slowpath flush for NMI */ #endif } -- 2.16.1