Skip to content

Commit bf638a6

Browse files
LuBaolujoergroedel
authored andcommitted
iommu/vt-d: Use rcu_lock in get_resv_regions
Commit 5f64ce5 ("iommu/vt-d: Duplicate iommu_resv_region objects per device list") converted rcu_lock in get_resv_regions to dmar_global_lock to allow sleeping in iommu_alloc_resv_region(). This introduced possible recursive locking if get_resv_regions is called from within a section where intel_iommu_init() already holds dmar_global_lock. Especially, after commit 57365a0 ("iommu: Move bus setup to IOMMU device registration"), below lockdep splats could always be seen. ============================================ WARNING: possible recursive locking detected 6.0.0-rc4+ #325 Tainted: G I -------------------------------------------- swapper/0/1 is trying to acquire lock: ffffffffa8a18c90 (dmar_global_lock){++++}-{3:3}, at: intel_iommu_get_resv_regions+0x25/0x270 but task is already holding lock: ffffffffa8a18c90 (dmar_global_lock){++++}-{3:3}, at: intel_iommu_init+0x36d/0x6ea ... Call Trace: <TASK> dump_stack_lvl+0x48/0x5f __lock_acquire.cold.73+0xad/0x2bb lock_acquire+0xc2/0x2e0 ? intel_iommu_get_resv_regions+0x25/0x270 ? lock_is_held_type+0x9d/0x110 down_read+0x42/0x150 ? intel_iommu_get_resv_regions+0x25/0x270 intel_iommu_get_resv_regions+0x25/0x270 iommu_create_device_direct_mappings.isra.28+0x8d/0x1c0 ? iommu_get_dma_cookie+0x6d/0x90 bus_iommu_probe+0x19f/0x2e0 iommu_device_register+0xd4/0x130 intel_iommu_init+0x3e1/0x6ea ? iommu_setup+0x289/0x289 ? rdinit_setup+0x34/0x34 pci_iommu_init+0x12/0x3a do_one_initcall+0x65/0x320 ? rdinit_setup+0x34/0x34 ? rcu_read_lock_sched_held+0x5a/0x80 kernel_init_freeable+0x28a/0x2f3 ? rest_init+0x1b0/0x1b0 kernel_init+0x1a/0x130 ret_from_fork+0x1f/0x30 </TASK> This rolls back dmar_global_lock to rcu_lock in get_resv_regions to avoid the lockdep splat. Fixes: 57365a0 ("iommu: Move bus setup to IOMMU device registration") Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Tested-by: Alex Williamson <alex.williamson@redhat.com> Link: https://lore.kernel.org/r/20220927053109.4053662-3-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent 0251d01 commit bf638a6

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

drivers/iommu/intel/iommu.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -4534,7 +4534,7 @@ static void intel_iommu_get_resv_regions(struct device *device,
45344534
struct device *i_dev;
45354535
int i;
45364536

4537-
down_read(&dmar_global_lock);
4537+
rcu_read_lock();
45384538
for_each_rmrr_units(rmrr) {
45394539
for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
45404540
i, i_dev) {
@@ -4553,14 +4553,14 @@ static void intel_iommu_get_resv_regions(struct device *device,
45534553

45544554
resv = iommu_alloc_resv_region(rmrr->base_address,
45554555
length, prot, type,
4556-
GFP_KERNEL);
4556+
GFP_ATOMIC);
45574557
if (!resv)
45584558
break;
45594559

45604560
list_add_tail(&resv->list, head);
45614561
}
45624562
}
4563-
up_read(&dmar_global_lock);
4563+
rcu_read_unlock();
45644564

45654565
#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
45664566
if (dev_is_pci(device)) {

0 commit comments

Comments
 (0)