iommu/arm-smmu: Allow using a threaded handler for context interrupts
authorGeorgi Djakov <quic_c_gdjako@quicinc.com>
Wed, 17 Apr 2024 13:37:27 +0000 (06:37 -0700)
committerWill Deacon <will@kernel.org>
Thu, 18 Apr 2024 14:48:01 +0000 (15:48 +0100)
Threaded IRQ handlers run in a less critical context compared to normal
IRQs, so they can perform more complex and time-consuming operations
without causing significant delays in other parts of the kernel.
During a context fault, it might be needed to do more processing and
gather debug information from TBUs in the handler. These operations may
sleep, so add an option to use a threaded IRQ handler in these cases.

Signed-off-by: Georgi Djakov <quic_c_gdjako@quicinc.com>
Link: https://lore.kernel.org/r/20240417133731.2055383-4-quic_c_gdjako@quicinc.com
Signed-off-by: Will Deacon <will@kernel.org>
drivers/iommu/arm/arm-smmu/arm-smmu.c
drivers/iommu/arm/arm-smmu/arm-smmu.h

index 5935f44e1d1d64a3e0aeebc620b15a72d41fd873..87c81f75cf844bd58492091bede23a1f2cb867ee 100644 (file)
@@ -806,8 +806,16 @@ static int arm_smmu_init_domain_context(struct arm_smmu_domain *smmu_domain,
        else
                context_fault = arm_smmu_context_fault;
 
-       ret = devm_request_irq(smmu->dev, irq, context_fault, IRQF_SHARED,
-                              "arm-smmu-context-fault", smmu_domain);
+       if (smmu->impl && smmu->impl->context_fault_needs_threaded_irq)
+               ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
+                                               context_fault,
+                                               IRQF_ONESHOT | IRQF_SHARED,
+                                               "arm-smmu-context-fault",
+                                               smmu_domain);
+       else
+               ret = devm_request_irq(smmu->dev, irq, context_fault, IRQF_SHARED,
+                                      "arm-smmu-context-fault", smmu_domain);
+
        if (ret < 0) {
                dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
                        cfg->irptndx, irq);
index 1670e95c4637e8104ef14ba168a14edbdb95e942..4765c6945c344dec36d250fde94d9134c0fe194a 100644 (file)
@@ -438,6 +438,7 @@ struct arm_smmu_impl {
        int (*def_domain_type)(struct device *dev);
        irqreturn_t (*global_fault)(int irq, void *dev);
        irqreturn_t (*context_fault)(int irq, void *dev);
+       bool context_fault_needs_threaded_irq;
        int (*alloc_context_bank)(struct arm_smmu_domain *smmu_domain,
                                  struct arm_smmu_device *smmu,
                                  struct device *dev, int start);