Since non-threaded IRQ handlers can't use IRQF_ONESHOT and we return directly from the IRQ handler after queueing a worker thread, the IRQ handler will be called continuously on level-triggered interrupts. At least on the author's platform, this causes CPU stalls detected by rcu_preempt, since the IRQ handler will be called too many times. This patch emulates IRQF_ONESHOT behaviour by disabling the IRQ in the IRQ handler and re-enabling it again at the end of the worker thread. --- drivers/tty/serial/sc16is7xx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index edb5305..8a6aa71 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -695,12 +695,15 @@ static void sc16is7xx_ist(struct kthread_work *ws) for (i = 0; i < s->devtype->nr_uart; ++i) sc16is7xx_port_irq(s, i); + + enable_irq(s->p[0].port.irq); } static irqreturn_t sc16is7xx_irq(int irq, void *dev_id) { struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id; + disable_irq_nosync(irq); queue_kthread_work(&s->kworker, &s->irq_work); return IRQ_HANDLED; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html