Messages in this thread | | | Date | Thu, 8 Nov 2018 13:45:10 +0900 | From | Sergey Senozhatsky <> | Subject | Re: [PATCH 3/3] lockdep: Use line-buffered printk() for lockdep messages. |
| |
On (11/07/18 16:19), Petr Mladek wrote: > > syzbot is sometimes getting mixed output like below due to concurrent > > printk(). Mitigate such output by using line-buffered printk() API. > > > > @@ -2421,18 +2458,20 @@ static void check_chain_key(struct task_struct *curr) > > print_usage_bug_scenario(struct held_lock *lock) > > { > > struct lock_class *class = hlock_class(lock); > > + struct printk_buffer *buf = get_printk_buffer(); > > > > printk(" Possible unsafe locking scenario:\n\n"); > > printk(" CPU0\n"); > > printk(" ----\n"); > > - printk(" lock("); > > - __print_lock_name(class); > > - printk(KERN_CONT ");\n"); > > + printk_buffered(buf, " lock("); > > + __print_lock_name(class, buf); > > + printk_buffered(buf, ");\n"); > > printk(" <Interrupt>\n"); > > - printk(" lock("); > > - __print_lock_name(class); > > - printk(KERN_CONT ");\n"); > > + printk_buffered(buf, " lock("); > > + __print_lock_name(class, buf); > > + printk_buffered(buf, ");\n"); > > printk("\n *** DEADLOCK ***\n\n"); > > + put_printk_buffer(buf); > > } > > > > static int > > I really hope that the maze of pr_cont() calls in lockdep.c is the most > complicated one that we would meet.
Hmm... Yes, buffered/seq_buf printk looks like a hard-to-use API, when it comes to real world cases like this.
So... here is a random and wild idea.
We actually already have an easy-to-use buffered printk. And it's per-CPU. And it makes all printk-s on this CPU to behave like as if they were called on UP system. And it cures pr_cont(). And it doesn't require anyone to learn any new printk API names. And it doesn't require any additional maintenance work. And it doesn't require any printk->buffered_printk conversions. And it's already in the kernel. And we gave it a name. And it's printk_safe.
a) lockdep reporting path should be atomic. And it's not a hot path, so local_irq_save/local_irq_restore will not cause a lot of trouble there probably.
b) We already have some lockdep reports coming via printk_safe. All those printk->console_driver->scheduler->lockdep printk->console_driver->timekeeping->lockdep etc.
came via printk_safe path. So it's not a complete novelty.
c) printk_safe sections can nest.
d) No premature flushes. Everything looks the way it was supposed to look.
e) There are no out-of-line printk-s. We keep the actual order of events.
f) We flush it on panic.
g) Low maintenance costs.
So, can we just do the following? /* a sketch */
lockdep.c printk_safe_enter_irqsave(flags); lockdep_report(); printk_safe_exit_irqrestore(flags);
-ss
| |