Re: [PATCH] uio: eliminate extraneous irq thread under CONFIG_PREEMPT_RT
Chris Packham <[email protected]>
| Newsgroups | dev.linux.lists.linux-rt-devel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-rt-users |
|---|---|
| Message-ID | <[email protected]> |
Hi Sebastian, On 20/08/2026 03:06, Sebastian Andrzej Siewior wrote: > Chris, what was the use case to split this? I was dealing with having a UIO interrupt for an input on a PCA9539. There's some more info on the original email thread[1] but basically because the PCA9539 inputs are nested __setup_irq() enforces that anyone requesting them does so with a threaded interrupt. https://lore.kernel.org/all/[email protected]/ > > On 2026-08-19 15:01:00 [+0000], Mike Schanne wrote: >> Commit f8a27dfa4b82d442af1c0645a5acc70cc97c67f6 ("uio: use threaded >> interrupts") makes all uio interrupts threaded by default. However >> under CONFIG_PREEMPT_RT, all interrupts are already threaded. This >> results in 2 irq threads per uio instance, adding an unnecessary >> extra context switch per interrupt. >> >> Do not request a threaded interrupt for uio under CONFIG_PREEMPT_RT >> >> Signed-off-by: Michael Schanne [email protected]<mailto:[email protected]> >> --- >> drivers/uio/uio.c | 17 +++++++++++++---- >> 1 file changed, 13 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c >> index 004a549c6..4e28777ac 100644 >> --- a/drivers/uio/uio.c >> +++ b/drivers/uio/uio.c >> @@ -448,8 +448,12 @@ static irqreturn_t uio_interrupt_handler(int irq, void *dev_id) >> irqreturn_t ret; >> ret = idev->info->handler(irq, idev->info); >> - if (ret == IRQ_HANDLED) >> - ret = IRQ_WAKE_THREAD; >> + if (ret == IRQ_HANDLED) { >> + if (IS_ENABLED(CONFIG_PREEMPT_RT)) >> + uio_event_notify(idev->info); >> + else >> + ret = IRQ_WAKE_THREAD; >> + } >> return ret; >> } >> @@ -1038,8 +1042,13 @@ int __uio_register_device(struct module *owner, >> * FDs at the time of unregister and therefore may not be >> * freed until they are released. >> */ >> - ret = request_threaded_irq(info->irq, uio_interrupt_handler, uio_interrupt_thread, >> - info->irq_flags, info->name, idev); >> + if (IS_ENABLED(CONFIG_PREEMPT_RT)) { >> + ret = request_irq(info->irq, uio_interrupt_handler, >> + info->irq_flags, info->name, idev); >> + } else { >> + ret = request_threaded_irq(info->irq, uio_interrupt_handler, uio_interrupt_thread, >> + info->irq_flags, info->name, idev); >> + } >> if (ret) { >> info->uio_dev = NULL; >> goto err_request_irq; > Sebastian