Messages in this thread | | | Date | Tue, 15 Mar 2016 11:03:23 +0100 | From | Jan Kara <> | Subject | Re: [RFC][PATCH v4 1/2] printk: Make printk() completely async |
| |
> + 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 <jack@suse.com> SUSE Labs, CR
| |