Lock(&iommu->lock) without disabling irq causes lockdep warnings. [ 12.703950] ======================================================== [ 12.703962] WARNING: possible irq lock inversion dependency detected [ 12.703975] 5.9.0-rc6+ #659 Not tainted [ 12.703983] -------------------------------------------------------- [ 12.703995] systemd-udevd/284 just changed the state of lock: [ 12.704007] ffffffffbd6ff4d8 (device_domain_lock){..-.}-{2:2}, at: iommu_flush_dev_iotlb.part.57+0x2e/0x90 [ 12.704031] but this lock took another, SOFTIRQ-unsafe lock in the past: [ 12.704043] (&iommu->lock){+.+.}-{2:2} [ 12.704045] and interrupts could create inverse lock ordering between them. [ 12.704073] other info that might help us debug this: [ 12.704085] Possible interrupt unsafe locking scenario: [ 12.704097] CPU0 CPU1 [ 12.704106] ---- ---- [ 12.704115] lock(&iommu->lock); [ 12.704123] local_irq_disable(); [ 12.704134] lock(device_domain_lock); [ 12.704146] lock(&iommu->lock); [ 12.704158] <Interrupt> [ 12.704164] lock(device_domain_lock); [ 12.704174] *** DEADLOCK ***
Unified · Split
| @@ -2664,7 +2664,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu, · 2663 unmodified lines | |||
| 2664 | } | 2664 | } |
| 2665 | 2665 | ||
| 2666 | /* Setup the PASID entry for requests without PASID: */ | 2666 | /* Setup the PASID entry for requests without PASID: */ |
| 2667 | spin_lock(&iommu->lock); | 2667 | spin_lock_irqsave(&iommu->lock, flags); |
| 2668 | if (hw_pass_through && domain_type_is_si(domain)) | 2668 | if (hw_pass_through && domain_type_is_si(domain)) |
| 2669 | ret = intel_pasid_setup_pass_through(iommu, domain, | 2669 | ret = intel_pasid_setup_pass_through(iommu, domain, |
| 2670 | dev, PASID_RID2PASID); | 2670 | dev, PASID_RID2PASID); |
| @@ -2674,7 +2674,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu, · 3 unmodified lines | |||
| 2674 | else | 2674 | else |
| 2675 | ret = intel_pasid_setup_second_level(iommu, domain, | 2675 | ret = intel_pasid_setup_second_level(iommu, domain, |
| 2676 | dev, PASID_RID2PASID); | 2676 | dev, PASID_RID2PASID); |
| 2677 | spin_unlock(&iommu->lock); | 2677 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 2678 | if (ret) { | 2678 | if (ret) { |
| 2679 | dev_err(dev, "Setup RID2PASID failed\n"); | 2679 | dev_err(dev, "Setup RID2PASID failed\n"); |
| 2680 | dmar_remove_one_dev_info(dev); | 2680 | dmar_remove_one_dev_info(dev); |