Re: [PATCH v9 11/12] iommu/arm-smmu-v3: Invoke pm_runtime before hw access
flat view
From: Daniel Mentz <hidden>
Date: 2026-08-30 21:11:35
Also in:
linux-iommu
On Tue, Jul 28, 2026 at 2:10 PM Pranjal Shrivastava [off-list ref] wrote:
quoted hunk ↗ jump to hunk
@@ -2386,6 +2407,34 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev) static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); + /* + * Use a non-sleeping get to avoid a circular dependency deadlock + * with arm_smmu_runtime_suspend(). + * + * When using a combined_irq, the suspend thread waits for pending + * threaded handlers to complete. If the IRQ thread blocks waiting + * for the PM core, it creates a deadlock: + * + * [Suspend Thread] | [IRQ Thread] + * pm_runtime_suspend() | + * state = RPM_SUSPENDING; | + * | IRQ fires + * | arm_smmu_rpm_get() + * | sleeps (waiting for suspend) + * arm_smmu_runtime_suspend() | + * ... | + * synchronize_irq() | + * sleeps (waiting for IRQ) | + * + * <==== DEADLOCK ====> + * + * A non-sleeping get allows the thread to instantly drop the event + * if the device is suspending, safely bypassing the synchronize_irq() + * deadlock. + */ + if (!arm_smmu_rpm_get_if_active(smmu)) + return IRQ_NONE; + do { while (!queue_remove_raw(q, evt)) { arm_smmu_decode_event(smmu, evt, &event);
Sashiko has the following concern:
Does returning IRQ_NONE here during transient PM states cause an interrupt storm or data loss? If the device is in a transient state (like RPM_SUSPENDING), this lockless check returns false and the thread aborts without acknowledging the hardware interrupt. For a level-triggered interrupt, this could cause an infinite interrupt storm since the line is unmasked on thread exit. Additionally, can aborting early here cause pending events to be permanently erased on resume? Because the thread aborts without updating the software llq.prod index via queue_sync_prod_in(), the stale pointer will be written back to the hardware EVTQ_PROD register during arm_smmu_device_reset() on resume.
I tend to agree with the concern about the stale producer index. Should we call queue_sync_prod_in(&smmu->evtq.q) in arm_smmu_runtime_suspend() after disabling the event queue? Also, how about printing a warning and returning IRQ_HANDLED if arm_smmu_rpm_get_if_active(smmu) returns false here?