Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756933AbcDGQe2 (ORCPT ); Thu, 7 Apr 2016 12:34:28 -0400 Received: from mail-pf0-f180.google.com ([209.85.192.180]:35951 "EHLO mail-pf0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756885AbcDGQeZ (ORCPT ); Thu, 7 Apr 2016 12:34:25 -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 Subject: [PATCH v11 3/3] printk: make printk.synchronous param rw Date: Fri, 8 Apr 2016 02:31:47 +0900 Message-Id: <1460050307-3718-4-git-send-email-sergey.senozhatsky@gmail.com> X-Mailer: git-send-email 2.8.0 In-Reply-To: <1460050307-3718-1-git-send-email-sergey.senozhatsky@gmail.com> References: <1460050307-3718-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 Content-Length: 3854 Lines: 127 Change `synchronous' printk param to be RW, so user space can change printk mode back and forth to/from sync mode (which is considered to be more reliable). Signed-off-by: Sergey Senozhatsky --- kernel/printk/printk.c | 63 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 89f5441..5ae6f73 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -288,9 +288,6 @@ static u32 log_buf_len = __LOG_BUF_LEN; /* Control whether printing to console must be synchronous. */ static bool __read_mostly printk_sync = true; -module_param_named(synchronous, printk_sync, bool, S_IRUGO); -MODULE_PARM_DESC(synchronous, "make printing to console synchronous"); - /* Printing kthread for async printk */ static struct task_struct *printk_kthread; /* When `true' printing thread has messages to print */ @@ -1785,7 +1782,7 @@ asmlinkage int vprintk_emit(int facility, int level, * operate in sync mode once panic() occurred. */ if (console_loglevel != CONSOLE_LOGLEVEL_MOTORMOUTH && - printk_kthread) { + !printk_sync && printk_kthread) { /* Offload printing to a schedulable context. */ printk_kthread_need_flush_console = true; wake_up_process(printk_kthread); @@ -2757,6 +2754,16 @@ static int __init printk_late_init(void) late_initcall(printk_late_init); #if defined CONFIG_PRINTK +/* + * kernel_param_ops.set is called from two places: + * - from parse_args()->printk_sync_set(), when we can't kthread_run(), so + * we just set the param value. The actual initalization happens later, + * from late_initcall(). + * + * - from user space via sysfs knob; we can kthread_run() there (if needed). + */ +static bool printk_initcall_done; + static int printk_kthread_func(void *data) { while (1) { @@ -2780,11 +2787,7 @@ static int printk_kthread_func(void *data) return 0; } -/* - * Init async printk via late_initcall, after core/arch/device/etc. - * initialization. - */ -static int __init init_printk_kthread(void) +static int __init_printk_kthread(void) { struct task_struct *thread; struct sched_param param = { @@ -2794,6 +2797,9 @@ static int __init init_printk_kthread(void) if (printk_sync) return 0; + if (printk_kthread) + return 0; + thread = kthread_run(printk_kthread_func, NULL, "printk"); if (IS_ERR(thread)) { pr_err("printk: unable to create printing thread\n"); @@ -2805,6 +2811,43 @@ static int __init init_printk_kthread(void) printk_kthread = thread; return 0; } + +static int printk_sync_set(const char *val, const struct kernel_param *kp) +{ + static DEFINE_MUTEX(printk_sync_lock); + int ret; + + mutex_lock(&printk_sync_lock); + ret = param_set_bool(val, kp); + if (ret) { + mutex_unlock(&printk_sync_lock); + return ret; + } + + if (printk_initcall_done) + ret = __init_printk_kthread(); + mutex_unlock(&printk_sync_lock); + return ret; +} + +static const struct kernel_param_ops param_ops_printk_sync = { + .set = printk_sync_set, + .get = param_get_bool, +}; + +module_param_cb(synchronous, ¶m_ops_printk_sync, &printk_sync, + S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(synchronous, "make printing to console synchronous"); + +/* + * Init async printk via late_initcall, after core/arch/device/etc. + * initialization. + */ +static __init int init_printk_kthread(void) +{ + printk_initcall_done = true; + return __init_printk_kthread(); +} late_initcall(init_printk_kthread); /* @@ -2820,7 +2863,7 @@ 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_kthread) { + if (!printk_sync && printk_kthread) { wake_up_process(printk_kthread); } else { /* -- 2.8.0