From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965435AbcCOKDT (ORCPT ); Tue, 15 Mar 2016 06:03:19 -0400 Received: from mx2.suse.de ([195.135.220.15]:43031 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932585AbcCOKDO (ORCPT ); Tue, 15 Mar 2016 06:03:14 -0400 Date: Tue, 15 Mar 2016 11:03:23 +0100 From: Jan Kara To: Sergey Senozhatsky Cc: Andrew Morton , Jan Kara , Petr Mladek , Tejun Heo , Tetsuo Handa , linux-kernel@vger.kernel.org, Byungchul Park , Sergey Senozhatsky , Jan Kara Subject: Re: [RFC][PATCH v4 1/2] printk: Make printk() completely async Message-ID: <20160315100323.GF17942@quack.suse.cz> References: <1457964820-4642-1-git-send-email-sergey.senozhatsky@gmail.com> <1457964820-4642-2-git-send-email-sergey.senozhatsky@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1457964820-4642-2-git-send-email-sergey.senozhatsky@gmail.com> User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org > + if (!sync_print) { > + if (printk_thread && !in_panic) { > + /* > + * This will wakeup the printing kthread and offload > + * printing to a schedulable context. > + */ > + __this_cpu_or(printk_pending, > + PRINTK_PENDING_KTHREAD_OUTPUT); > + irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); > + } else if (in_sched) { > + /* > + * @in_sched messages may come too early, when we don't > + * yet have @printk_thread. We can't print deferred > + * messages directly, because this may deadlock, route > + * them via IRQ context. > + */ > + __this_cpu_or(printk_pending, > + PRINTK_PENDING_IRQ_OUTPUT); > + irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); > + } else { > + sync_print = true; > + } > + } I'm a bit undecided whether we want to go through irq work even for the common case of !in_sched messages or whether we want to directly call wake_up() in that case. Maybe I'd do it like: if (!sync_print) { if (in_sched) { __this_cpu_or(printk_pending, PRINTK_PENDING_IRQ_OUTPUT); irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); } else if (printk_thread && !in_panic) { wake_up(&printing_wait); } else { sync_print = true; } } and the wake_up_klogd_work_func() would look like: static void wake_up_klogd_work_func(struct irq_work *irq_work) { int pending = __this_cpu_xchg(printk_pending, 0); if (pending & PRINTK_PENDING_OUTPUT) { if (printk_thread) { wake_up(&printing_wait); } else { /* * If trylock fails, someone else is doing the printing */ if (console_trylock()) console_unlock(); } } ... Honza -- Jan Kara SUSE Labs, CR