[PATCH] genirq: Warn about using IRQF_ONESHOT without a threaded handler

Sebastian Andrzej Siewior posted 1 patch 3 weeks, 5 days ago
There is a newer version of this series
kernel/irq/manage.c | 7 +++++++
1 file changed, 7 insertions(+)
[PATCH] genirq: Warn about using IRQF_ONESHOT without a threaded handler
Posted by Sebastian Andrzej Siewior 3 weeks, 5 days ago
IRQF_ONESHOT disables the interrupt source until after the threaded
handler completed its work. This is needed to allow the threaded handler
to run - otherwise the CPU will get back to the interrupt handler
because the interrupt source remains active and the threaded handler
will not able to do its work.

Specifying IRQF_ONESHOT without a threaded handler does not make sense.
It could be a leftover if the handler _was_ threaded and changed back to
primary and the flag was not removed. This can be problematic in the
`threadirqs' case because the handler is exempt from forced-threading.
This in turn can become a problem on a PREEMPT_RT system if the handler
attempts to acquire sleeping locks.

Warn about missing threaded handlers with the IRQF_ONESHOT flag.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---

This popped up after Stefan Klug posted
   https://lore.kernel.org/all/20260105-sklug-v6-16-topic-dw100-v3-1-dev-v1-3-65af34d04fd8@ideasonboard.com/

There are a few drivers in tree which will trigger this warning such as
- arch/arm/mach-versatile/spc.c
- drivers/char/tpm/tpm_tis_spi_cr50.c
- drivers/edac/altera_edac.c
- drivers/i2c/busses/i2c-k1.c
- …

just to name a few. I *think* if IRQF_ONESHOT was on purpose and not
driven by copy/paste then the they wanted to use IRQF_NO_THREAD.

 kernel/irq/manage.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 349ae7979da0e..18a8405cadb26 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1473,6 +1473,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 	if (!(new->flags & IRQF_TRIGGER_MASK))
 		new->flags |= irqd_get_trigger_type(&desc->irq_data);
 
+	/*
+	 * IRQF_ONESHOT means the interrupt source in the IRQ chip will be
+	 * masked until the threaded handled is done. If there is no thread
+	 * handler then it makes no sense to have IRQF_ONESHOT.
+	 */
+	WARN_ON_ONCE(new->flags & IRQF_ONESHOT && !new->thread_fn);
+
 	/*
 	 * Check whether the interrupt nests into another interrupt
 	 * thread.
-- 
2.51.0
Re: [PATCH] genirq: Warn about using IRQF_ONESHOT without a threaded handler
Posted by Laurent Pinchart 3 weeks, 4 days ago
Hi Sebastian,

Thank you for the patch.

On Mon, Jan 12, 2026 at 02:40:13PM +0100, Sebastian Andrzej Siewior wrote:
> IRQF_ONESHOT disables the interrupt source until after the threaded
> handler completed its work. This is needed to allow the threaded handler
> to run - otherwise the CPU will get back to the interrupt handler
> because the interrupt source remains active and the threaded handler
> will not able to do its work.
> 
> Specifying IRQF_ONESHOT without a threaded handler does not make sense.
> It could be a leftover if the handler _was_ threaded and changed back to
> primary and the flag was not removed. This can be problematic in the
> `threadirqs' case because the handler is exempt from forced-threading.
> This in turn can become a problem on a PREEMPT_RT system if the handler
> attempts to acquire sleeping locks.
> 
> Warn about missing threaded handlers with the IRQF_ONESHOT flag.
> 
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
> 
> This popped up after Stefan Klug posted
>    https://lore.kernel.org/all/20260105-sklug-v6-16-topic-dw100-v3-1-dev-v1-3-65af34d04fd8@ideasonboard.com/

This patch would have saved us from trouble with the DW100 driver, so

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

I wonder if some people would object due to panic_on_warn, but I think
the issue will be caught early when testing kernel updates way before it
should hit users.

> There are a few drivers in tree which will trigger this warning such as
> - arch/arm/mach-versatile/spc.c
> - drivers/char/tpm/tpm_tis_spi_cr50.c
> - drivers/edac/altera_edac.c
> - drivers/i2c/busses/i2c-k1.c
> - …
> 
> just to name a few. I *think* if IRQF_ONESHOT was on purpose and not
> driven by copy/paste then the they wanted to use IRQF_NO_THREAD.
> 
>  kernel/irq/manage.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
> index 349ae7979da0e..18a8405cadb26 100644
> --- a/kernel/irq/manage.c
> +++ b/kernel/irq/manage.c
> @@ -1473,6 +1473,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
>  	if (!(new->flags & IRQF_TRIGGER_MASK))
>  		new->flags |= irqd_get_trigger_type(&desc->irq_data);
>  
> +	/*
> +	 * IRQF_ONESHOT means the interrupt source in the IRQ chip will be
> +	 * masked until the threaded handled is done. If there is no thread
> +	 * handler then it makes no sense to have IRQF_ONESHOT.
> +	 */
> +	WARN_ON_ONCE(new->flags & IRQF_ONESHOT && !new->thread_fn);
> +
>  	/*
>  	 * Check whether the interrupt nests into another interrupt
>  	 * thread.

-- 
Regards,

Laurent Pinchart
Re: [PATCH] genirq: Warn about using IRQF_ONESHOT without a threaded handler
Posted by Stefan Klug 3 weeks, 3 days ago
Hi Sebastian,

Quoting Laurent Pinchart (2026-01-12 18:46:16)
> Hi Sebastian,
> 
> Thank you for the patch.
> 
> On Mon, Jan 12, 2026 at 02:40:13PM +0100, Sebastian Andrzej Siewior wrote:
> > IRQF_ONESHOT disables the interrupt source until after the threaded
> > handler completed its work. This is needed to allow the threaded handler
> > to run - otherwise the CPU will get back to the interrupt handler
> > because the interrupt source remains active and the threaded handler
> > will not able to do its work.
> > 
> > Specifying IRQF_ONESHOT without a threaded handler does not make sense.
> > It could be a leftover if the handler _was_ threaded and changed back to
> > primary and the flag was not removed. This can be problematic in the
> > `threadirqs' case because the handler is exempt from forced-threading.
> > This in turn can become a problem on a PREEMPT_RT system if the handler
> > attempts to acquire sleeping locks.
> > 
> > Warn about missing threaded handlers with the IRQF_ONESHOT flag.
> > 
> > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> > ---
> > 
> > This popped up after Stefan Klug posted
> >    https://lore.kernel.org/all/20260105-sklug-v6-16-topic-dw100-v3-1-dev-v1-3-65af34d04fd8@ideasonboard.com/
> 
> This patch would have saved us from trouble with the DW100 driver, so

I can only agree here :-)

Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>

Thanks,
Stefan

> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> I wonder if some people would object due to panic_on_warn, but I think
> the issue will be caught early when testing kernel updates way before it
> should hit users.
> 
> > There are a few drivers in tree which will trigger this warning such as
> > - arch/arm/mach-versatile/spc.c
> > - drivers/char/tpm/tpm_tis_spi_cr50.c
> > - drivers/edac/altera_edac.c
> > - drivers/i2c/busses/i2c-k1.c
> > - …
> > 
> > just to name a few. I *think* if IRQF_ONESHOT was on purpose and not
> > driven by copy/paste then the they wanted to use IRQF_NO_THREAD.
> > 
> >  kernel/irq/manage.c | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
> > index 349ae7979da0e..18a8405cadb26 100644
> > --- a/kernel/irq/manage.c
> > +++ b/kernel/irq/manage.c
> > @@ -1473,6 +1473,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
> >       if (!(new->flags & IRQF_TRIGGER_MASK))
> >               new->flags |= irqd_get_trigger_type(&desc->irq_data);
> >  
> > +     /*
> > +      * IRQF_ONESHOT means the interrupt source in the IRQ chip will be
> > +      * masked until the threaded handled is done. If there is no thread
> > +      * handler then it makes no sense to have IRQF_ONESHOT.
> > +      */
> > +     WARN_ON_ONCE(new->flags & IRQF_ONESHOT && !new->thread_fn);
> > +
> >       /*
> >        * Check whether the interrupt nests into another interrupt
> >        * thread.
> 
> -- 
> Regards,
> 
> Laurent Pinchart
[tip: irq/core] genirq: Warn about using IRQF_ONESHOT without a threaded handler
Posted by tip-bot2 for Sebastian Andrzej Siewior 3 weeks, 4 days ago
The following commit has been merged into the irq/core branch of tip:

Commit-ID:     aef30c8d569c0f31715447525640044c74feb26f
Gitweb:        https://git.kernel.org/tip/aef30c8d569c0f31715447525640044c74feb26f
Author:        Sebastian Andrzej Siewior <bigeasy@linutronix.de>
AuthorDate:    Mon, 12 Jan 2026 14:40:13 +01:00
Committer:     Thomas Gleixner <tglx@kernel.org>
CommitterDate: Tue, 13 Jan 2026 09:56:25 +01:00

genirq: Warn about using IRQF_ONESHOT without a threaded handler

IRQF_ONESHOT disables the interrupt source until after the threaded
handler completed its work. This is needed to allow the threaded handler
to run - otherwise the CPU will get back to the interrupt handler
because the interrupt source remains active and the threaded handler
will not able to do its work.

Specifying IRQF_ONESHOT without a threaded handler does not make sense.
It could be a leftover if the handler _was_ threaded and changed back to
primary and the flag was not removed. This can be problematic in the
`threadirqs' case because the handler is exempt from forced-threading.
This in turn can become a problem on a PREEMPT_RT system if the handler
attempts to acquire sleeping locks.

Warn about missing threaded handlers with the IRQF_ONESHOT flag.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patch.msgid.link/20260112134013.eQWyReHR@linutronix.de
---
 kernel/irq/manage.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index bc2d36b..dde1aa6 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1474,6 +1474,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 		new->flags |= irqd_get_trigger_type(&desc->irq_data);
 
 	/*
+	 * IRQF_ONESHOT means the interrupt source in the IRQ chip will be
+	 * masked until the threaded handled is done. If there is no thread
+	 * handler then it makes no sense to have IRQF_ONESHOT.
+	 */
+	WARN_ON_ONCE(new->flags & IRQF_ONESHOT && !new->thread_fn);
+
+	/*
 	 * Check whether the interrupt nests into another interrupt
 	 * thread.
 	 */
Re: [tip: irq/core] genirq: Warn about using IRQF_ONESHOT without a threaded handler
Posted by Sebastian Andrzej Siewior 3 weeks, 4 days ago
On 2026-01-13 08:58:56 [-0000], tip-bot2 for Sebastian Andrzej Siewior wrote:
> The following commit has been merged into the irq/core branch of tip:
> 
> Commit-ID:     aef30c8d569c0f31715447525640044c74feb26f
> Gitweb:        https://git.kernel.org/tip/aef30c8d569c0f31715447525640044c74feb26f
> Author:        Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> AuthorDate:    Mon, 12 Jan 2026 14:40:13 +01:00
> Committer:     Thomas Gleixner <tglx@kernel.org>
> CommitterDate: Tue, 13 Jan 2026 09:56:25 +01:00
> 
> genirq: Warn about using IRQF_ONESHOT without a threaded handler

Should I pro-active send some patches to those users which I know do it
wrong? Or do we simply wait?

Sebastian
Re: [tip: irq/core] genirq: Warn about using IRQF_ONESHOT without a threaded handler
Posted by Bert Karwatzki 4 days, 15 hours ago
Since commit 
aef30c8d569c ("genirq: Warn about using IRQF_ONESHOT without a threaded handler")
has been merged into linux-next the following warning appears when booting my 
MSI Alpha 15 laptop (running linux-next-20260130 with debian stable/trixie):

[    8.436584] [   T1180] ------------[ cut here ]------------
[    8.436811] [   T1180] WARNING: kernel/irq/manage.c:1502 at __setup_irq+0x4fa/0x730, CPU#15: iio-sensor-prox/1180
[    8.436817] [   T1180] Modules linked in: rfcomm bnep nls_ascii nls_cp437 vfat fat snd_hda_codec_generic btusb btrtl snd_hda_codec_atihdmi btintel snd_hda_codec_hdmi btbcm uvcvideo btmtk videobuf2_vmalloc videobuf2_memops snd_hda_intel uvc videobuf2_v4l2 snd_intel_dspcfg snd_hda_codec snd_acp3x_rn snd_soc_dmic snd_acp3x_pdm_dma bluetooth snd_hda_core snd_soc_core snd_hwdep videodev snd_pcm_oss snd_mixer_oss snd_pcm snd_rn_pci_acp3x hid_sensor_magn_3d hid_sensor_prox hid_sensor_accel_3d hid_sensor_als hid_sensor_gyro_3d videobuf2_common snd_acp_config snd_soc_acpi hid_sensor_trigger msi_wmi ecdh_generic ecc mc sparse_keymap wmi_bmof snd_timer k10temp snd snd_pci_acp3x ccp ac soundcore industrialio_triggered_buffer battery kfifo_buf button industrialio amd_pmc hid_sensor_iio_common joydev evdev mt7921e mt7921_common mt792x_lib mt76_connac_lib mt76 mac80211 libarc4 cfg80211 rfkill msr fuse nvme_fabrics efi_pstore configfs efivarfs autofs4 ext4 mbcache jbd2 usbhid amdgpu amdxcp i2c_algo_bit drm_client_lib drm_ttm_helper ttm xhci_pci
[    8.437165] [   T1180]  drm_exec drm_panel_backlight_quirks xhci_hcd gpu_sched drm_suballoc_helper hid_sensor_hub drm_buddy mfd_core hid_multitouch hid_generic drm_display_helper usbcore i2c_hid_acpi psmouse amd_sfh i2c_hid drm_kms_helper nvme hid serio_raw nvme_core r8169 i2c_piix4 cec i2c_smbus usb_common crc16 i2c_designware_platform i2c_designware_core
[    8.437185] [   T1180] CPU: 15 UID: 0 PID: 1180 Comm: iio-sensor-prox Tainted: G        W           6.19.0-rc7-next-20260130-iiodebug-00002-g2875feff2cee #292 PREEMPT(full) 
[    8.437188] [   T1180] Tainted: [W]=WARN
[    8.437189] [   T1180] Hardware name: Micro-Star International Co., Ltd. Alpha 15 B5EEK/MS-158L, BIOS E158LAMS.10F 11/11/2024
[    8.437190] [   T1180] RIP: 0010:__setup_irq+0x4fa/0x730
[    8.437193] [   T1180] Code: e7 e8 ca 6f 00 00 e9 7e fd ff ff b8 01 00 00 00 48 c7 c2 ff ff ff ff f3 48 0f bc d2 c4 e2 e9 f7 c0 48 89 43 48 e9 d8 fd ff ff <0f> 0b 85 c9 0f 85 8c 00 00 00 81 e2 00 00 01 00 0f 85 7d fb ff ff
[    8.437194] [   T1180] RSP: 0018:ffffc3b6c46d7c70 EFLAGS: 00010246
[    8.437196] [   T1180] RAX: 0000000000002000 RBX: ffffa04c05503e80 RCX: 0000000000000000
[    8.437197] [   T1180] RDX: 0000000000000400 RSI: ffffa04c112e0e00 RDI: ffffffffc181cac0
[    8.437198] [   T1180] RBP: 0000000000000077 R08: 0000000000000000 R09: ffffa04c05503e80
[    8.437199] [   T1180] R10: 0000000000000001 R11: 0000000000000003 R12: 0000000000000077
[    8.437200] [   T1180] R13: ffffa04c112e0e00 R14: ffffa04c112e0e00 R15: ffffa04c05503e80
[    8.437201] [   T1180] FS:  00007f447c23f940(0000) GS:ffffa04f2cb1d000(0000) knlGS:0000000000000000
[    8.437203] [   T1180] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    8.437204] [   T1180] CR2: 0000559507dd86d8 CR3: 0000000103b55000 CR4: 0000000000750ef0
[    8.437205] [   T1180] PKRU: 55555554
[    8.437206] [   T1180] Call Trace:
[    8.437207] [   T1180]  <TASK>
[    8.437209] [   T1180]  request_threaded_irq+0xdf/0x170
[    8.437213] [   T1180]  iio_trigger_attach_poll_func.cold+0x3e/0x111 [industrialio]
[    8.437220] [   T1180]  __iio_update_buffers.cold+0x5c/0x70 [industrialio]
[    8.437224] [   T1180]  ? __entry_text_end+0x1021d7/0x1021db
[    8.437227] [   T1180]  ? _dev_info+0x6a/0x84
[    8.437232] [   T1180]  enable_store+0x95/0xe7 [industrialio]
[    8.437236] [   T1180]  kernfs_fop_write_iter+0x14b/0x200
[    8.437240] [   T1180]  vfs_write+0x21d/0x420
[    8.437244] [   T1180]  ksys_write+0x5e/0xd0
[    8.437246] [   T1180]  do_syscall_64+0x66/0x380
[    8.437250] [   T1180]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[    8.437252] [   T1180] RIP: 0033:0x7f447c6459ee
[    8.437254] [   T1180] Code: 08 0f 85 f5 4b ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 80 00 00 00 00 48 83 ec 08
[    8.437255] [   T1180] RSP: 002b:00007ffc44efa068 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[    8.437257] [   T1180] RAX: ffffffffffffffda RBX: 00007f447c23f940 RCX: 00007f447c6459ee
[    8.437258] [   T1180] RDX: 0000000000000001 RSI: 00007ffc44efa210 RDI: 0000000000000008
[    8.437259] [   T1180] RBP: 00007ffc44efa210 R08: 0000000000000000 R09: 0000000000000000
[    8.437260] [   T1180] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
[    8.437261] [   T1180] R13: 0000559507d382a0 R14: 00007f447c78fee0 R15: 0000000000000001
[    8.437263] [   T1180]  </TASK>
[    8.437264] [   T1180] ---[ end trace 0000000000000000 ]---

The warning appears because iio_triggered_buffer_setup_ext() (in 
drivers/iio/buffer/industrialio-triggered-buffer.c) is called with thread = NULL
during the probe of the iio device and calls iio_alloc_pollfunc()
(in drivers/iio/industrialio-trigger.c) with thread = NULL and type = IRQF_ONESHOT.

A simple fix could be this:

diff --git a/drivers/iio/buffer/industrialio-triggered-buffer.c b/drivers/iio/buffer/industrialio-triggered-buffer.c
index 9bf75dee7ff8..40eea3a44724 100644
--- a/drivers/iio/buffer/industrialio-triggered-buffer.c
+++ b/drivers/iio/buffer/industrialio-triggered-buffer.c
@@ -64,7 +64,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev,
 
        indio_dev->pollfunc = iio_alloc_pollfunc(h,
                                                 thread,
-                                                IRQF_ONESHOT,
+                                                thread ? IRQF_ONESHOT : 0,
                                                 indio_dev,
                                                 "%s_consumer%d",
                                                 indio_dev->name,


Are there any problems with this?

Bert Karwatzki
Re: [tip: irq/core] genirq: Warn about using IRQF_ONESHOT without a threaded handler
Posted by Sebastian Andrzej Siewior 4 days, 6 hours ago
On 2026-02-03 00:27:40 [+0100], Bert Karwatzki wrote:
> 
> The warning appears because iio_triggered_buffer_setup_ext() (in 
> drivers/iio/buffer/industrialio-triggered-buffer.c) is called with thread = NULL
> during the probe of the iio device and calls iio_alloc_pollfunc()
> (in drivers/iio/industrialio-trigger.c) with thread = NULL and type = IRQF_ONESHOT.
> 
> A simple fix could be this:
> 
> diff --git a/drivers/iio/buffer/industrialio-triggered-buffer.c b/drivers/iio/buffer/industrialio-triggered-buffer.c
> index 9bf75dee7ff8..40eea3a44724 100644
> --- a/drivers/iio/buffer/industrialio-triggered-buffer.c
> +++ b/drivers/iio/buffer/industrialio-triggered-buffer.c
> @@ -64,7 +64,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev,
>  
>         indio_dev->pollfunc = iio_alloc_pollfunc(h,
>                                                  thread,
> -                                                IRQF_ONESHOT,
> +                                                thread ? IRQF_ONESHOT : 0,
>                                                  indio_dev,
>                                                  "%s_consumer%d",
>                                                  indio_dev->name,
> 
> 
> Are there any problems with this?

Urgh. Haven't seen those.

Looking at all the users of of *iio_triggered_buffer_setup*() the
primary handler is either NULL or iio_pollfunc_store_time(). 
So IRQF_ONESHOST should work all the time.

Then there is 
- drivers/iio/adc/vf610_adc.c 
- drivers/iio/common/hid-sensors/hid-sensor-trigger.c

They use iio_pollfunc_store_time() as primary and have no secondary.
This would trigger the warning but not having a secondary handler while
returning IRQF_WAKE_THREAD should create a warning of its own.
What did I miss?

> Bert Karwatzki

Sebastian
Re: [tip: irq/core] genirq: Warn about using IRQF_ONESHOT without a threaded handler
Posted by srinivas pandruvada 3 days, 21 hours ago
On Tue, 2026-02-03 at 09:38 +0100, Sebastian Andrzej Siewior wrote:
> On 2026-02-03 00:27:40 [+0100], Bert Karwatzki wrote:
> > 
> > The warning appears because iio_triggered_buffer_setup_ext() (in 
> > drivers/iio/buffer/industrialio-triggered-buffer.c) is called with
> > thread = NULL
> > during the probe of the iio device and calls iio_alloc_pollfunc()
> > (in drivers/iio/industrialio-trigger.c) with thread = NULL and type
> > = IRQF_ONESHOT.
> > 
> > A simple fix could be this:
> > 
> > diff --git a/drivers/iio/buffer/industrialio-triggered-buffer.c
> > b/drivers/iio/buffer/industrialio-triggered-buffer.c
> > index 9bf75dee7ff8..40eea3a44724 100644
> > --- a/drivers/iio/buffer/industrialio-triggered-buffer.c
> > +++ b/drivers/iio/buffer/industrialio-triggered-buffer.c
> > @@ -64,7 +64,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev
> > *indio_dev,
> >  
> >         indio_dev->pollfunc = iio_alloc_pollfunc(h,
> >                                                  thread,
> > -                                                IRQF_ONESHOT,
> > +                                                thread ?
> > IRQF_ONESHOT : 0,
> >                                                  indio_dev,
> >                                                  "%s_consumer%d",
> >                                                  indio_dev->name,
> > 
> > 
> > Are there any problems with this?
> 
> Urgh. Haven't seen those.
> 
> Looking at all the users of of *iio_triggered_buffer_setup*() the
> primary handler is either NULL or iio_pollfunc_store_time(). 
> So IRQF_ONESHOST should work all the time.
> 
> Then there is 
> - drivers/iio/adc/vf610_adc.c 
> - drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> 
> They use iio_pollfunc_store_time() as primary and have no secondary.
> This would trigger the warning but not having a secondary handler
> while
> returning IRQF_WAKE_THREAD should create a warning of its own.
> What did I miss?
> 

hid-sensor doesn't need a bh handler. This patch can fix. 

diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 5540e2d28f4a..b2b09b544f43 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -227,6 +227,11 @@ static const struct iio_trigger_ops
hid_sensor_trigger_ops = {
        .set_trigger_state = &hid_sensor_data_rdy_trigger_set_state,
 };
 
+static irqreturn_t triggered_buffer_handler(int irq, void *p)
+{
+        return IRQ_HANDLED;
+}
+
 int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char
*name,
                                struct hid_sensor_common *attrb)
 {
@@ -240,7 +245,8 @@ int hid_sensor_setup_trigger(struct iio_dev
*indio_dev, const char *name,
                fifo_attrs = NULL;
 
        ret = iio_triggered_buffer_setup_ext(indio_dev,
-                                            &iio_pollfunc_store_time,
NULL,
+                                            &iio_pollfunc_store_time,
+                                            triggered_buffer_handler,
                                             IIO_BUFFER_DIRECTION_IN,
                                             NULL, fifo_attrs);
        if (ret) {


Or add it to industrialio-triggered-buffer.c as a common handler for
all caller with no bh, whatever Jonathan prefers.


Thanks,
Srinivas



> > Bert Karwatzki
> 
> Sebastian
Re: [tip: irq/core] genirq: Warn about using IRQF_ONESHOT without a threaded handler
Posted by Bert Karwatzki 4 days, 4 hours ago
Am Dienstag, dem 03.02.2026 um 09:38 +0100 schrieb Sebastian Andrzej Siewior:
> On 2026-02-03 00:27:40 [+0100], Bert Karwatzki wrote:
> > 
> > The warning appears because iio_triggered_buffer_setup_ext() (in 
> > drivers/iio/buffer/industrialio-triggered-buffer.c) is called with thread = NULL
> > during the probe of the iio device and calls iio_alloc_pollfunc()
> > (in drivers/iio/industrialio-trigger.c) with thread = NULL and type = IRQF_ONESHOT.
> > 
> > A simple fix could be this:
> > 
> > diff --git a/drivers/iio/buffer/industrialio-triggered-buffer.c b/drivers/iio/buffer/industrialio-triggered-buffer.c
> > index 9bf75dee7ff8..40eea3a44724 100644
> > --- a/drivers/iio/buffer/industrialio-triggered-buffer.c
> > +++ b/drivers/iio/buffer/industrialio-triggered-buffer.c
> > @@ -64,7 +64,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev,
> >  
> >         indio_dev->pollfunc = iio_alloc_pollfunc(h,
> >                                                  thread,
> > -                                                IRQF_ONESHOT,
> > +                                                thread ? IRQF_ONESHOT : 0,
> >                                                  indio_dev,
> >                                                  "%s_consumer%d",
> >                                                  indio_dev->name,
> > 
> > 
> > Are there any problems with this?
> 
> Urgh. Haven't seen those.
> 
> Looking at all the users of of *iio_triggered_buffer_setup*() the
> primary handler is either NULL or iio_pollfunc_store_time(). 
> So IRQF_ONESHOST should work all the time.
> 
> Then there is 
> - drivers/iio/adc/vf610_adc.c 
> - drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> 
> They use iio_pollfunc_store_time() as primary and have no secondary.
> This would trigger the warning but not having a secondary handler while
> returning IRQF_WAKE_THREAD should create a warning of its own.

Yes, this should call warn_no_thread() when the interrupt is triggered, but
I don't know if these sensors are actually functional on my laptop (I've never
tried to use them).

So I installed libiio-utils from debian and this is the output from
iio_info:


# iio_info 
iio_info version: 0.26 (git tag:v0.26)
Libiio version: 0.26 (git tag: v0.26) backends: local xml ip usb serial
IIO context created with local backend.
Backend version: 0.26 (git tag: v0.26)
Backend description string: Linux lisa 6.19.0-rc7-next-20260130-iiofix-00001-gc30f943f5645 #293 SMP PREEMPT_DYNAMIC Tue Feb  3 00:32:20 CET 2026 x86_64
IIO context has 2 attributes:
	local,kernel: 6.19.0-rc7-next-20260130-iiofix-00001-gc30f943f5645
	uri: local:
IIO context has 21 devices:
	hwmon0: acpitz
		1 channels found:
			temp1:  (input)
			1 channel-specific attributes found:
				attr  0: input value: 59000
		No trigger on this device
	hwmon1: nvme
		2 channels found:
			temp3:  (input)
			2 channel-specific attributes found:
				attr  0: input value: 77850
				attr  1: label value: Sensor 2
			temp1:  (input)
			6 channel-specific attributes found:
				attr  0: alarm value: 0
				attr  1: crit value: 88850
				attr  2: input value: 29850
				attr  3: label value: Composite
				attr  4: max value: 83850
				attr  5: min value: -20150
		No trigger on this device
	hwmon2: nvme
		4 channels found:
			temp2:  (input)
			4 channel-specific attributes found:
				attr  0: input value: 32850
				attr  1: label value: Sensor 1
				attr  2: max value: 65261850
				attr  3: min value: -273150
			temp6:  (input)
			4 channel-specific attributes found:
				attr  0: input value: 35850
				attr  1: label value: Sensor 5
				attr  2: max value: 65261850
				attr  3: min value: -273150
			temp3:  (input)
			4 channel-specific attributes found:
				attr  0: input value: 30850
				attr  1: label value: Sensor 2
				attr  2: max value: 65261850
				attr  3: min value: -273150
			temp1:  (input)
			6 channel-specific attributes found:
				attr  0: alarm value: 0
				attr  1: crit value: 79850
				attr  2: input value: 31850
				attr  3: label value: Composite
				attr  4: max value: 69850
				attr  5: min value: -273150
		No trigger on this device
	hwmon3: amdgpu
		7 channels found:
			temp3:  (input)
			5 channel-specific attributes found:
				attr  0: crit value: 100000
				attr  1: crit_hyst value: -273150
				attr  2: emergency value: 105000
				attr  3: input value: 46000
				attr  4: label value: mem
			temp2:  (input)
			5 channel-specific attributes found:
				attr  0: crit value: 100000
				attr  1: crit_hyst value: -273150
				attr  2: emergency value: 105000
				attr  3: input value: 46000
				attr  4: label value: junction
			in0:  (input)
			2 channel-specific attributes found:
				attr  0: input value: 6
				attr  1: label value: vddgfx
			power1:  (input)
			6 channel-specific attributes found:
				attr  0: average value: 4000000
				attr  1: cap value: 65000000
				attr  2: cap_default value: 65000000
				attr  3: cap_max value: 65000000
				attr  4: cap_min value: 65000000
				attr  5: label value: PPT
			fan1:  (input)
			5 channel-specific attributes found:
				attr  0: enable value: 0
				attr  1: input value: 0
				attr  2: max value: 3300
				attr  3: min value: 0
				attr  4: target value: 0
			temp1:  (input)
			5 channel-specific attributes found:
				attr  0: crit value: 100000
				attr  1: crit_hyst value: -273150
				attr  2: emergency value: 105000
				attr  3: input value: 46000
				attr  4: label value: edge
			pwm1:  (input)
			4 channel-specific attributes found:
				attr  0: enable value: 2
				attr  1: max value: 255
				attr  2: min value: 0
				attr  3: pwm1 value: 91
		4 device-specific attributes found:
				attr  0: freq1_input value: 0
				attr  1: freq1_label value: sclk
				attr  2: freq2_input value: 96000000
				attr  3: freq2_label value: mclk
		No trigger on this device
	hwmon4: amdgpu
		4 channels found:
			in1:  (input)
			2 channel-specific attributes found:
				attr  0: input value: 962
				attr  1: label value: vddnb
			in0:  (input)
			2 channel-specific attributes found:
				attr  0: input value: 1099
				attr  1: label value: vddgfx
			power1:  (input)
			2 channel-specific attributes found:
				attr  0: input value: 17000000
				attr  1: label value: PPT
			temp1:  (input)
			2 channel-specific attributes found:
				attr  0: input value: 49000
				attr  1: label value: edge
		2 device-specific attributes found:
				attr  0: freq1_input value: 400000000
				attr  1: freq1_label value: sclk
		No trigger on this device
	hwmon5: ADP1
		0 channels found:
		No trigger on this device
	hwmon6: k10temp
		1 channels found:
			temp1:  (input)
			2 channel-specific attributes found:
				attr  0: input value: 56500
				attr  1: label value: Tctl
		No trigger on this device
	hwmon7: BAT1
		2 channels found:
			in0:  (input)
			1 channel-specific attributes found:
				attr  0: input value: 15801
			curr1:  (input)
			1 channel-specific attributes found:
				attr  0: input value: 0
		No trigger on this device
	hwmon8: mt7921_phy0
		1 channels found:
			temp1:  (input)
			1 channel-specific attributes found:
				attr  0: input value: 42000
		No trigger on this device
	iio:device0: als (buffer capable)
		6 channels found:
			intensity_both:  (input, index: 0, format: le:S32/32>>0)
			6 channel-specific attributes found:
				attr  0: hysteresis ERROR: Invalid argument (22)
				attr  1: hysteresis_relative value: 0.000000
				attr  2: offset value: 0
				attr  3: raw value: 0
				attr  4: sampling_frequency value: 10.000000
				attr  5: scale value: 0.100000000
			illuminance:  (input, index: 1, format: le:S32/32>>0)
			6 channel-specific attributes found:
				attr  0: hysteresis ERROR: Invalid argument (22)
				attr  1: hysteresis_relative value: 0.000000
				attr  2: offset value: 0
				attr  3: raw value: 0
				attr  4: sampling_frequency value: 10.000000
				attr  5: scale value: 0.100000000
			colortemp:  (input, WARN:iio_channel_get_type()=UNKNOWN, index: 2, format: le:S32/32>>0)
			6 channel-specific attributes found:
				attr  0: hysteresis ERROR: Invalid argument (22)
				attr  1: hysteresis_relative value: 0.000000
				attr  2: offset value: 0
				attr  3: raw value: -16843009
				attr  4: sampling_frequency value: 10.000000
				attr  5: scale value: 0.100000000
			chromaticity_x:  (input, WARN:iio_channel_get_type()=UNKNOWN, index: 3, format: le:S32/32>>0)
			6 channel-specific attributes found:
				attr  0: hysteresis ERROR: Invalid argument (22)
				attr  1: hysteresis_relative value: 0.000000
				attr  2: offset value: 0
				attr  3: raw value: -1073087296
				attr  4: sampling_frequency value: 10.000000
				attr  5: scale value: 0.100000000
			chromaticity_y:  (input, WARN:iio_channel_get_type()=UNKNOWN, index: 4, format: le:S32/32>>0)
			6 channel-specific attributes found:
				attr  0: hysteresis ERROR: Invalid argument (22)
				attr  1: hysteresis_relative value: 0.000000
				attr  2: offset value: 0
				attr  3: raw value: 0
				attr  4: sampling_frequency value: 10.000000
				attr  5: scale value: 0.100000000
			timestamp:  (input, index: 5, format: le:S64/64>>0)
		1 device-specific attributes found:
				attr  0: current_timestamp_clock value: realtime
		2 buffer-specific attributes found:
				attr  0: data_available value: 0
				attr  1: direction value: in
		Current trigger: trigger0(als-dev0)
	iio:device1: als (buffer capable)
		6 channels found:
			intensity_both:  (input, index: 0, format: le:S32/32>>0)
			6 channel-specific attributes found:
				attr  0: hysteresis ERROR: Invalid argument (22)
				attr  1: hysteresis_relative value: 0.000000
				attr  2: offset value: 0
				attr  3: raw value: 0
				attr  4: sampling_frequency value: 0.000000
				attr  5: scale value: 0.100000000
			illuminance:  (input, index: 1, format: le:S32/32>>0)
			6 channel-specific attributes found:
				attr  0: hysteresis ERROR: Invalid argument (22)
				attr  1: hysteresis_relative value: 0.000000
				attr  2: offset value: 0
				attr  3: raw value: 0
				attr  4: sampling_frequency value: 0.000000
				attr  5: scale value: 0.100000000
			colortemp:  (input, WARN:iio_channel_get_type()=UNKNOWN, index: 2, format: le:S32/32>>0)
			6 channel-specific attributes found:
				attr  0: hysteresis ERROR: Invalid argument (22)
				attr  1: hysteresis_relative value: 0.000000
				attr  2: offset value: 0
				attr  3: raw value: 0
				attr  4: sampling_frequency value: 0.000000
				attr  5: scale value: 0.100000000
			chromaticity_x:  (input, WARN:iio_channel_get_type()=UNKNOWN, index: 3, format: le:S32/32>>0)
			6 channel-specific attributes found:
				attr  0: hysteresis ERROR: Invalid argument (22)
				attr  1: hysteresis_relative value: 0.000000
				attr  2: offset value: 0
				attr  3: raw value: 0
				attr  4: sampling_frequency value: 0.000000
				attr  5: scale value: 0.100000000
			chromaticity_y:  (input, WARN:iio_channel_get_type()=UNKNOWN, index: 4, format: le:S32/32>>0)
			6 channel-specific attributes found:
				attr  0: hysteresis ERROR: Invalid argument (22)
				attr  1: hysteresis_relative value: 0.000000
				attr  2: offset value: 0
				attr  3: raw value: 0
				attr  4: sampling_frequency value: 0.000000
				attr  5: scale value: 0.100000000
			timestamp:  (input, index: 5, format: le:S64/64>>0)
		1 device-specific attributes found:
				attr  0: current_timestamp_clock value: realtime
		2 buffer-specific attributes found:
				attr  0: data_available value: 0
				attr  1: direction value: in
		Current trigger: trigger1(als-dev1)
	iio:device2: gyro_3d (buffer capable)
		4 channels found:
			anglvel_x:  (input, index: 0, format: le:S32/32>>0)
			5 channel-specific attributes found:
				attr  0: hysteresis value: 0.000000
				attr  1: offset value: 0
				attr  2: raw value: 0
				attr  3: sampling_frequency value: 0.000000
				attr  4: scale value: 0.000174532
			anglvel_y:  (input, index: 1, format: le:S32/32>>0)
			5 channel-specific attributes found:
				attr  0: hysteresis value: 0.000000
				attr  1: offset value: 0
				attr  2: raw value: 0
				attr  3: sampling_frequency value: 0.000000
				attr  4: scale value: 0.000174532
			anglvel_z:  (input, index: 2, format: le:S32/32>>0)
			5 channel-specific attributes found:
				attr  0: hysteresis value: 0.000000
				attr  1: offset value: 0
				attr  2: raw value: 0
				attr  3: sampling_frequency value: 0.000000
				attr  4: scale value: 0.000174532
			timestamp:  (input, index: 3, format: le:S64/64>>0)
		1 device-specific attributes found:
				attr  0: current_timestamp_clock value: realtime
		2 buffer-specific attributes found:
				attr  0: data_available value: 0
				attr  1: direction value: in
		Current trigger: trigger2(gyro_3d-dev2)
	iio:device3: prox (buffer capable)
		1 channels found:
			proximity0:  (input, index: 0, format: le:s8/32>>0)
			5 channel-specific attributes found:
				attr  0: hysteresis ERROR: Invalid argument (22)
				attr  1: offset value: 0
				attr  2: raw value: 15
				attr  3: sampling_frequency value: 10.000000
				attr  4: scale value: 1.000000000
		2 buffer-specific attributes found:
				attr  0: data_available value: 0
				attr  1: direction value: in
		Current trigger: trigger4(prox-dev3)
	iio:device4: accel_3d (buffer capable)
		4 channels found:
			accel_x:  (input, index: 0, format: le:S32/32>>0)
			5 channel-specific attributes found:
				attr  0: hysteresis value: 0.000000
				attr  1: offset value: 0
				attr  2: raw value: 0
				attr  3: sampling_frequency value: 10.000000
				attr  4: scale value: 0.098066500
			accel_y:  (input, index: 1, format: le:S32/32>>0)
			5 channel-specific attributes found:
				attr  0: hysteresis value: 0.000000
				attr  1: offset value: 0
				attr  2: raw value: 0
				attr  3: sampling_frequency value: 10.000000
				attr  4: scale value: 0.098066500
			accel_z:  (input, index: 2, format: le:S32/32>>0)
			5 channel-specific attributes found:
				attr  0: hysteresis value: 0.000000
				attr  1: offset value: 0
				attr  2: raw value: 0
				attr  3: sampling_frequency value: 10.000000
				attr  4: scale value: 0.098066500
			timestamp:  (input, index: 3, format: le:S64/64>>0)
		1 device-specific attributes found:
				attr  0: current_timestamp_clock value: realtime
		2 buffer-specific attributes found:
				attr  0: data_available value: 0
				attr  1: direction value: in
		Current trigger: trigger3(accel_3d-dev4)
	iio:device5: magn_3d (buffer capable)
		3 channels found:
			magn_x:  (input, index: 0, format: le:S32/32>>0)
			5 channel-specific attributes found:
				attr  0: hysteresis value: 0.000000
				attr  1: offset value: 0
				attr  2: raw value: 0
				attr  3: sampling_frequency value: 0.000000
				attr  4: scale value: 0.000001000
			magn_y:  (input, index: 1, format: le:S32/32>>0)
			5 channel-specific attributes found:
				attr  0: hysteresis value: 0.000000
				attr  1: offset value: 0
				attr  2: raw value: 0
				attr  3: sampling_frequency value: 0.000000
				attr  4: scale value: 0.000001000
			magn_z:  (input, index: 2, format: le:S32/32>>0)
			5 channel-specific attributes found:
				attr  0: hysteresis value: 0.000000
				attr  1: offset value: 0
				attr  2: raw value: 0
				attr  3: sampling_frequency value: 0.000000
				attr  4: scale value: 0.000001000
		2 buffer-specific attributes found:
				attr  0: data_available value: 0
				attr  1: direction value: in
		Current trigger: trigger5(magn_3d-dev5)
	trigger0: als-dev0
		0 channels found:
		No trigger on this device
	trigger1: als-dev1
		0 channels found:
		No trigger on this device
	trigger2: gyro_3d-dev2
		0 channels found:
		No trigger on this device
	trigger3: accel_3d-dev4
		0 channels found:
		No trigger on this device
	trigger4: prox-dev3
		0 channels found:
		No trigger on this device
	trigger5: magn_3d-dev5
		0 channels found:
		No trigger on this device

The iio:device* sensors all report 0 for the "offset value", so these
sensors are maybe non-fuctional.


> What did I miss?

I don't think you missed something, but the thread function being NULL here
could a problem on devices where these sensors actually work. (Or perhaps these sensors
need to be polled and the interrupts never trigger (?))

Bert Karwatzki
> 
Re: [tip: irq/core] genirq: Warn about using IRQF_ONESHOT without a threaded handler
Posted by Sebastian Andrzej Siewior 3 days, 23 hours ago
On 2026-02-03 11:43:53 [+0100], Bert Karwatzki wrote:
> Yes, this should call warn_no_thread() when the interrupt is triggered, but
> I don't know if these sensors are actually functional on my laptop (I've never
> tried to use them).
> 
> So I installed libiio-utils from debian and this is the output from
> iio_info:
…
> 
> The iio:device* sensors all report 0 for the "offset value", so these
> sensors are maybe non-fuctional.
> 
> 
> > What did I miss?
> 
> I don't think you missed something, but the thread function being NULL here
> could a problem on devices where these sensors actually work. (Or perhaps these sensors
> need to be polled and the interrupts never trigger (?))

I only found one handler where the thread handler was NULL and it
returned WAKE_THREAD. So this _is_ broken.
Was it one of the driver I mentioned? If so I suggest to fix those
first. I have no idea how this should work…

> Bert Karwatzki

Sebastian
Re: [tip: irq/core] genirq: Warn about using IRQF_ONESHOT without a threaded handler
Posted by Thomas Gleixner 3 weeks, 3 days ago
On Tue, Jan 13 2026 at 13:05, Sebastian Andrzej Siewior wrote:
> On 2026-01-13 08:58:56 [-0000], tip-bot2 for Sebastian Andrzej Siewior wrote:
>> The following commit has been merged into the irq/core branch of tip:
>> 
>> Commit-ID:     aef30c8d569c0f31715447525640044c74feb26f
>> Gitweb:        https://git.kernel.org/tip/aef30c8d569c0f31715447525640044c74feb26f
>> Author:        Sebastian Andrzej Siewior <bigeasy@linutronix.de>
>> AuthorDate:    Mon, 12 Jan 2026 14:40:13 +01:00
>> Committer:     Thomas Gleixner <tglx@kernel.org>
>> CommitterDate: Tue, 13 Jan 2026 09:56:25 +01:00
>> 
>> genirq: Warn about using IRQF_ONESHOT without a threaded handler
>
> Should I pro-active send some patches to those users which I know do it
> wrong? Or do we simply wait?

Just send fixes for them ...