Skip to content

icvs: don't request a non-threaded IRQ with IRQF_ONESHOT - #41

Open
jibsta210 wants to merge 1 commit into
intel:mainfrom
jibsta210:fix-cvs-irqf-oneshot
Open

icvs: don't request a non-threaded IRQ with IRQF_ONESHOT#41
jibsta210 wants to merge 1 commit into
intel:mainfrom
jibsta210:fix-cvs-irqf-oneshot

Conversation

@jibsta210

Copy link
Copy Markdown

cvs_init() registers cvs_irq_handler() as a primary (hardirq) handler via devm_request_irq() but passes IRQF_ONESHOT.

IRQF_ONESHOT is intended for threaded interrupts — it keeps the line masked after the hardirq until the threaded handler runs. cvs_irq_handler() has no threaded component (it only sets hostwake_event_arg and wakes a waitqueue), so the flag is inappropriate. On the Synaptics SVP7500 (06cb:0701) CVS bridge it leaves the device interrupt masked after an event, so the bridge stops delivering interrupts after a brief idle and wedges. libcamera then can no longer drive the sensor and falls back to the simple pipeline with no frames — the ov08x40 … Unable to get rectangle N … Inappropriate ioctl for device + simple-pipeline-fallback signature reported in #33, #31 and #36.

Dropping IRQF_ONESHOT restores reliable IRQ delivery and streaming; IRQF_NO_SUSPEND is kept so the line stays armed across suspend.

Tested on a Dell XPS 16 (Panther Lake, SVP7500 + ov08x40): with the change the RGB camera streams (500 frames @ 28.57 fps via libcamera cam); without it the bridge wedges after a brief idle.

cvs_init() registers cvs_irq_handler() as a primary (hardirq) handler via
devm_request_irq(), but passes IRQF_ONESHOT. IRQF_ONESHOT is intended for
threaded interrupts, where it keeps the interrupt line masked after the
hardirq until the threaded handler has run. cvs_irq_handler() has no
threaded component -- it only sets hostwake_event_arg and wakes a
waitqueue -- so IRQF_ONESHOT is inappropriate here.

On the Synaptics SVP7500 (06cb:0701) CVS bridge this leaves the device
interrupt masked after an event; the bridge then stops delivering
interrupts after a brief idle and wedges, after which libcamera can no
longer drive the sensor and falls back to the "simple" pipeline with no
frames flowing. Dropping IRQF_ONESHOT restores reliable interrupt delivery
and streaming.

Keep IRQF_NO_SUSPEND so the interrupt remains armed across system suspend.

Fixes: 6a93817 ("gpio resources")
Signed-off-by: Jake Steinman <[email protected]>
@AskeFC

AskeFC commented Jul 9, 2026

Copy link
Copy Markdown

Please merge this 🙏

@milamberspace

Copy link
Copy Markdown

Confirming this on a different platform and CVS bridge, which I think strengthens the case that it's not bridge-specific.

  • Machine: Dell XPS 13 9350, Intel Lunar Lake
  • CVS bridge: Lattice AI USB 2.0 (2ac1:20c9), ACPI INTC10DE:00 — not the Synaptics SVP7500 from the description
  • Kernel: 7.1.3 (CONFIG_INTEL_VSC, intel_cvs via DKMS)

Without this change, every cold boot logs the WARN at __setup_irq from cvs_init():

WARNING: kernel/irq/manage.c:1502 at __setup_irq+0x50c/0x720
 ? __pfx_cvs_irq_handler+0x10/0x10 [intel_cvs]
 request_threaded_irq+0xe2/0x1b0
 devm_request_threaded_irq+0x81/0x120
 cvs_common_probe.cold+0x25e/0x3d6 [intel_cvs]

With IRQF_ONESHOT dropped, the WARN is gone and the probe is clean (Transfer of ownership success), camera + mic stream fine.

One data point in the other direction: on this Lattice bridge I did not observe the post-idle wedge you saw on the SVP7500 — the camera worked even with the buggy flag (once the sensor-ownership race was worked around separately). So on this bridge the flag looks harmless at runtime but still trips the WARN and taints the kernel on every boot. Either way the flag is wrong for a non-threaded handler, and this is the correct minimal fix. +1 for merging.

@disy-mk

disy-mk commented Sep 8, 2026

Copy link
Copy Markdown

Same WARNING here on a second Dell XPS 16 DA16260 (Panther Lake, Core Ultra X7 358H, Synaptics SVP7500 06cb:0701 + ov08x40 — same model as yours), on Arch kernels 7.1.8 (linux-ptl) and stock 7.1.9, with intel_cvs built via DKMS from cf5844d. Current main (845d6f8) still carries the same IRQF_ONESHOT | IRQF_NO_SUSPEND line at intel_cvs.c:40, so this applies as-is.

WARNING: kernel/irq/manage.c:1502 at __setup_irq+0x641/0x750
new->flags & IRQF_ONESHOT && !new->thread_fn
 request_threaded_irq+0xe7/0x1e0
 devm_request_threaded_irq+0x94/0x160
 cvs_common_probe.cold+0x2bf/0x4ba [intel_cvs]

The check is new: torvalds/linux@aef30c8 ("genirq: Warn about using IRQF_ONESHOT without a threaded handler", authored 2026-01-12) landed in v7.0-rc1 and is not in v6.19 or stable, so every 7.x kernel with the i2c-bound CVS device hits it on each boot, while ≤ 6.19 — including the v6.7 the README was tested against — stays silent. It is a WARN_ON_ONCE, so probe still succeeds (ownership transfer ~210 ms later) and the IRQ is registered — but it sets TAINT_WARN on every boot (tainted = 12800 → W|O|E), which marks every later kernel bug report from these machines. Per that commit the flag also exempts the handler from forced threading under threadirqs, and cvs_irq_handler() calls wake_up_interruptible(), which takes a spinlock_t — a sleeping lock on PREEMPT_RT. Not exercised here (PREEMPT_DYNAMIC, no threadirqs); noting it only because it means this isn't purely cosmetic.

I have not hit the post-idle wedge from the description: the camera streamed fine after ~12.7 h, and the hostwake IRQ had fired 20 times in that period, so the line was not being left masked. Two differences that may matter, though: my userspace is icamerasrc/IPU7 via v4l2-relayd rather than libcamera, and my setup loads intel_cvs two seconds before ov08x40 as an ownership-race workaround — so take this as neither confirming nor contradicting your observation. The flag is wrong regardless: the handler has no threaded half, so IRQF_ONESHOT protects nothing, and keeping IRQF_NO_SUSPEND looks right.

Built this branch (688bc70) via DKMS and rebooted into 7.1.8: the WARNING is gone, tainted drops from 12800 to 12288 (O|E only), intel_cvs probes and completes the ownership transfer, the IRQ is registered (intel-gpio 20 i2c-INTC10E1:00), and the camera streams as before.

Tested-by: Manuel Knitza [email protected]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants