lkml.org 
[lkml]   [2016]   [Mar]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [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

\
 
 \ /
  Last update: 2016-03-15 11:41    [W:0.839 / U:0.016 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site