Received: by 10.223.176.46 with SMTP id f43csp3825767wra; Mon, 22 Jan 2018 23:05:48 -0800 (PST) X-Google-Smtp-Source: AH8x224zla5T4UuDTTchTi5NP2jGdfvU3yQM6Yp0VKK8sF3F1JBt3lZbRcaRRcxH5Z12A5I3v9z2 X-Received: by 2002:a17:902:9348:: with SMTP id g8-v6mr4668538plp.102.1516691148834; Mon, 22 Jan 2018 23:05:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516691148; cv=none; d=google.com; s=arc-20160816; b=PFXfFxp0SN3zkPYXfhvsVuHdI8VB17850DSZNxCv++bUbBkvAw/dYc/BzCYI0pziiJ iT6l+ZzjNLYrYRxJNQGbtfSc734ThXXiv3pS6TwtAIGkrXONxYOfSSblcReHIPtU8x3H CUNEHDutNbvoO6JptVF48SrVUg5ol/Q2z93AlIDP2pQa3SCidtrxZf/zsNEv5JOsoi3Y 4Q/gQ61CKK8CaZaupE1bYzb7TUZOFOajkMcN2HzawgLUOhwUY86k68OPq5z4YdEr9048 U/LS45IIk2Mzz4sAUfAtyLlyNkiuFwlYhZpmt3/P00yDy094O017HnM+kzrN3k/df+eO DURQ== 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=ZkR4i/h8+vO438DyjkqJMOppumxx9THkfr8VLULV5D4=; b=hf4bDw975udPIgeWfg1mdX+0pZH2UOU2yIhvirwUa7/J4O+daIjHhVTTTS6WqJBwmu 6Hv1dHO0zIohIhTczXenuBzl2UcOYz7roFQ5ohEytS0qGXGJZCsfPFGbe4gL8qQtrtT7 KEOr9jAgnBYQdXyVE6/BpcCed4KQG99mtQXpiVmrQRDiZl4QjDzwz1KB4wzZ74sQCDuW 8TPk3E/cYZgVxCVVYVehcQU726PTnxjGUFoeO8sVbQVRH80OIuLTaCQQwbjCLBwySI+3 rQWyImTv+osw0osOmWXwvi6Uf8kPOvSeljBkjFxoJ3bxvwdhkuthow9j/M6x9szWPow9 4s1g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=pOeEueQS; 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 t2-v6si4229013plo.811.2018.01.22.23.05.32; Mon, 22 Jan 2018 23:05:48 -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=pOeEueQS; 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 S1751155AbeAWHFI (ORCPT + 99 others); Tue, 23 Jan 2018 02:05:08 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:42119 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750907AbeAWHFG (ORCPT ); Tue, 23 Jan 2018 02:05:06 -0500 Received: by mail-pf0-f194.google.com with SMTP id b25so9054087pfd.9 for ; Mon, 22 Jan 2018 23:05:06 -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=ZkR4i/h8+vO438DyjkqJMOppumxx9THkfr8VLULV5D4=; b=pOeEueQSOdJNGAS4lVuvBeKbbPKMQiZqsNE1zAwMulO0mIoa+2WOF8jBFdSS5k/I12 Qx7c0JNGmJverQaiokk55VU6gfX/rbg8EnWhYqNua7VQTAed1kssTTVPqevTunPruwk7 JwgX38LBSItSvfn5AWDkcLb1XjLMi6G0BIkpDuZiHDAL9nabPvbtJefBkDHf2yollBTq IcZ25XIehvuKwHNGDY/uDg/43P6XALATIBSzPyDoH4iyDkUETlCUwGnQBc+jusYPfx5B klUoedhZnpnb2U7YHLIqnCUy4mWV9LdLfkVPxNNXtGKsWi4/V6LbxdMlg+hRGr+gcO0p 2nmw== 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=ZkR4i/h8+vO438DyjkqJMOppumxx9THkfr8VLULV5D4=; b=PAraH8xhVLiA24h54+sWr6W7aNxxPSs9SCrdGTRDzFjEVHjyHAnusHCtk7oTPjr50g wGZQDJSw+0ihuG8cTIfCDx3H5XljL/wIpnSv7lHXMei5Aupmw6de+IQxxD1Yxsu3YtF0 613vQ7UBT9WpOeGOQCd2SRoLYe5kjYRPfv3LZSWjKe33NdDLnwGniKEpRfyEvT2j4c2n h1dc+vOCAMNOSUWXx9tIfOdgZFVDqX/lA/fbkuAj+7v0+Aid31Mi0fv66E0vjD+iY33q ev1Z1cRdwff1rkhrHoBS8sdKHXE7NPW/vqDAXRCA+NdycGELDjSbRw1aWDUvRON6s2Bp o0rA== X-Gm-Message-State: AKwxytePKeM7kzFEoPvu0u8Uc6E12kZ3KKbvkriTwV5qej/vQTd9i3w/ mfA22gicj6/V+E2gNgoH+2E= X-Received: by 10.99.145.66 with SMTP id l63mr7981863pge.273.1516691106030; Mon, 22 Jan 2018 23:05:06 -0800 (PST) Received: from localhost ([39.7.50.209]) by smtp.gmail.com with ESMTPSA id j3sm2811322pfh.39.2018.01.22.23.05.04 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 22 Jan 2018 23:05:04 -0800 (PST) Date: Tue, 23 Jan 2018 16:05:01 +0900 From: Sergey Senozhatsky To: Sergey Senozhatsky Cc: Petr Mladek , Tejun Heo , Steven Rostedt , 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: <20180123070501.GA489@jagdpanzerIV> References: <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> <20180123064023.GA492@jagdpanzerIV> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180123064023.GA492@jagdpanzerIV> 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 On (01/23/18 15:40), Sergey Senozhatsky wrote: [..] > 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? A slightly reworked version: a) Do not check console_locked b) Do not have irq_work fast path for printk_safe buffer c) Which lets to union WQ/IRQ work structs - we use only IRQ work for NMI buffers, and only WQ work for SAFE buffers d) And also to refactor the code From: Sergey Senozhatsky Subject: [PATCH] printk/safe: use system_wq to flush printk_safe buffers --- kernel/printk/printk_safe.c | 52 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c index 3e3c2004bb23..6c8c82cedccb 100644 --- a/kernel/printk/printk_safe.c +++ b/kernel/printk/printk_safe.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "internal.h" @@ -49,7 +50,12 @@ static int printk_safe_irq_ready __read_mostly; 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 */ + union { + /* IRQ work that flushes NMI buffer */ + struct irq_work irq_flush_work; + /* WQ work that flushes SAFE buffer */ + struct work_struct wq_flush_work; + }; unsigned char buffer[SAFE_LOG_BUF_LEN]; }; @@ -61,10 +67,18 @@ 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); + irq_work_queue(&s->irq_flush_work); +} + +static void queue_wq_flush_work(struct printk_safe_seq_buf *s) +{ + if (printk_safe_irq_ready) + queue_work_on(smp_processor_id(), + system_wq, + &s->wq_flush_work); } /* @@ -89,7 +103,6 @@ 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); return 0; } @@ -112,7 +125,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; } @@ -186,12 +198,10 @@ static void report_message_lost(struct printk_safe_seq_buf *s) * Flush data from the associated per-CPU buffer. The function * can be called either via IRQ work or independently. */ -static void __printk_safe_flush(struct irq_work *work) +static void __printk_safe_flush(struct printk_safe_seq_buf *s) { static raw_spinlock_t read_lock = __RAW_SPIN_LOCK_INITIALIZER(read_lock); - struct printk_safe_seq_buf *s = - container_of(work, struct printk_safe_seq_buf, work); unsigned long flags; size_t len; int i; @@ -243,6 +253,22 @@ static void __printk_safe_flush(struct irq_work *work) raw_spin_unlock_irqrestore(&read_lock, flags); } +static void irq_flush_work_fn(struct irq_work *work) +{ + struct printk_safe_seq_buf *s = + container_of(work, struct printk_safe_seq_buf, irq_flush_work); + + __printk_safe_flush(s); +} + +static void wq_flush_work_fn(struct work_struct *work) +{ + struct printk_safe_seq_buf *s = + container_of(work, struct printk_safe_seq_buf, wq_flush_work); + + __printk_safe_flush(s); +} + /** * printk_safe_flush - flush all per-cpu nmi buffers. * @@ -256,9 +282,9 @@ void printk_safe_flush(void) for_each_possible_cpu(cpu) { #ifdef CONFIG_PRINTK_NMI - __printk_safe_flush(&per_cpu(nmi_print_seq, cpu).work); + __printk_safe_flush(this_cpu_ptr(&nmi_print_seq)); #endif - __printk_safe_flush(&per_cpu(safe_print_seq, cpu).work); + __printk_safe_flush(this_cpu_ptr(&safe_print_seq)); } } @@ -300,6 +326,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 +370,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_wq_flush_work(s); return printk_safe_log_store(s, fmt, args); } @@ -387,11 +415,11 @@ 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_WORK(&s->wq_flush_work, wq_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->irq_flush_work, irq_flush_work_fn); #endif } -- 2.16.1