Message ID | 20201019101109.753597069@linutronix.de |
---|---|
State | Superseded |
Headers | show |
Series | USB: Cleanup in_interupt/in_irq/in_atomic() usage | expand |
On Mon, Oct 26, 2020 at 01:47:53PM +0100, Sebastian Andrzej Siewior wrote: > On 2020-10-25 17:56:47 [+0100], Johan Hovold wrote: > > There's a ton of issues with this driver, but this is arguably making > > things worse. A line discipline may call write() from just about any > > context so we cannot rely on tty being non-NULL here (e.g. PPP). > > I wasn't aware of that. I've been looking at the callers each time a > `tty' was passed it looked like a preemptible context (due to mutex / > GFP_KERNEL) and so on. Yeah, the default line discipline only calls in preemptible context (these days), but others do not (e.g. see ppp_async_push()). Johan
--- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -477,10 +477,12 @@ static int keyspan_pda_write(struct tty_ count = (count > port->bulk_out_size) ? port->bulk_out_size : count; - /* Check if we might overrun the Tx buffer. If so, ask the - device how much room it really has. This is done only on - scheduler time, since usb_control_msg() sleeps. */ - if (count > priv->tx_room && !in_interrupt()) { + /* + * Check if we might overrun the Tx buffer. If so, ask the device + * how much room it really has. This can only be invoked for tty + * usage because the console write can't sleep. + */ + if (count > priv->tx_room && tty) { u8 *room; room = kmalloc(1, GFP_KERNEL);