Hi Peter, On 11/10/2016 07:44 PM, Peter Zijlstra wrote: > On Thu, Nov 10, 2016 at 09:56:41AM +0100, Thomas Gleixner wrote: >> On Thu, 10 Nov 2016, Lu Baolu wrote: >>> This seems to be a common issue for all early printk drivers. >> No. The other early printk drivers like serial do not have that problem as >> they simply do: >> >> while (*buf) { >> while (inb(UART) & TX_BUSY) >> cpu_relax(); >> outb(*buf++, UART); >> } > Right, which is why actual UARTs rule. If only laptops still had pinouts > for them life would be sooooo much better. > > Ideally the USB debug port would be a virtual UART and its interface as > simple and robust. > >> The wait for the UART to become ready is independent of the context as it >> solely depends on the hardware. >> >> As a result you can see the output from irq/nmi intermingled with the one >> from thread context, but that's the only problem they have. >> >> The only thing you can do to make this work is to prevent printing in NMI >> context: >> >> write() >> { >> if (in_nmi()) >> return; >> >> raw_spinlock_irqsave(&lock, flags); >> .... >> >> That fully serializes the writes and just ignores NMI context printks. Not >> optimal, but I fear that's all you can do. > I would also suggest telling the hardware people they have designed > something near the brink of useless. If you cannot do random exception > context debugging (#DB, #NMI, #MCE etc..) then there's a whole host of > problems that simply cannot be debugged. > > Also note that kdb runs from NMI context, so you'll not be able to > support that either. > Things become complicated when it comes to USB debug port. But it's still addressable. At this time, we can do it like this. write() { if (in_nmi() && raw_spin_is_locked(&lock)) return; raw_spinlock_irqsave(&lock, flags); .... This will filter some messages from NMI handler in case that another thread is holding the spinlock. I have no idea about how much chance could a debug user faces this. But it might further be fixed with below enhancement. write() { if (in_nmi() && raw_spin_is_locked(&lock)) { produce_a_pending_item_in_ring(); return; } raw_spinlock_irqsave(&lock, flags); while (!pending_item_ring_is_empty) consume_a_pending_item_in_ring(); .... We can design the pending item ring in a producer-consumer model. It's easy to avoid race between the producer and consumer. Best regards, Lu Baolu -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html