Messages in this thread Patch in this message | | | From | Sergey Senozhatsky <> | Subject | [PATCH] printk: make printk.synchronous param rw | Date | Sun, 24 Apr 2016 00:01:05 +0900 |
| |
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 <sergey.senozhatsky@gmail.com> Reviewed-by: Jan Kara <jack@suse.cz> ---
-- added Jan's Reviewed-by -- factored out async printk checks to can_printk_async()
kernel/printk/printk.c | 56 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 11 deletions(-)
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 89f5441..9345a29 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -288,14 +288,16 @@ 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 */ static bool printk_kthread_need_flush_console; +static inline bool can_printk_async(void) +{ + return !printk_sync && printk_kthread; +} + /* Return log buffer address */ char *log_buf_addr_get(void) { @@ -1785,7 +1787,7 @@ asmlinkage int vprintk_emit(int facility, int level, * operate in sync mode once panic() occurred. */ if (console_loglevel != CONSOLE_LOGLEVEL_MOTORMOUTH && - printk_kthread) { + can_printk_async()) { /* Offload printing to a schedulable context. */ printk_kthread_need_flush_console = true; wake_up_process(printk_kthread); @@ -2757,6 +2759,13 @@ static int __init printk_late_init(void) late_initcall(printk_late_init); #if defined CONFIG_PRINTK +/* + * Prevent starting printk_kthread from start_kernel()->parse_args(). + * It's not possible at this stage. Instead, do it via the inticall + * or a sysfs knob. + */ +static bool printk_kthread_can_run; + static int printk_kthread_func(void *data) { while (1) { @@ -2780,18 +2789,14 @@ 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 = { .sched_priority = MAX_RT_PRIO - 1, }; - if (printk_sync) + if (!printk_kthread_can_run || printk_sync || printk_kthread) return 0; thread = kthread_run(printk_kthread_func, NULL, "printk"); @@ -2805,6 +2810,35 @@ 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) +{ + int ret; + + ret = param_set_bool(val, kp); + if (ret) + return ret; + return __init_printk_kthread(); +} + +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/etc. + * initialization. + */ +static __init int init_printk_kthread(void) +{ + printk_kthread_can_run = true; + return __init_printk_kthread(); +} late_initcall(init_printk_kthread); /* @@ -2820,7 +2854,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 (can_printk_async()) { wake_up_process(printk_kthread); } else { /* -- 2.8.0
| |