diff options
Diffstat (limited to 'drivers/iommu/amd/iommu_v2.c')
-rw-r--r-- | drivers/iommu/amd/iommu_v2.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/iommu/amd/iommu_v2.c b/drivers/iommu/amd/iommu_v2.c index e56b137ceabd..afb3efd565b7 100644 --- a/drivers/iommu/amd/iommu_v2.c +++ b/drivers/iommu/amd/iommu_v2.c @@ -956,6 +956,7 @@ static void __exit amd_iommu_v2_exit(void) { struct device_state *dev_state, *next; unsigned long flags; + LIST_HEAD(freelist); if (!amd_iommu_v2_supported()) return; @@ -975,11 +976,20 @@ static void __exit amd_iommu_v2_exit(void) put_device_state(dev_state); list_del(&dev_state->list); - free_device_state(dev_state); + list_add_tail(&dev_state->list, &freelist); } spin_unlock_irqrestore(&state_lock, flags); + /* + * Since free_device_state waits on the count to be zero, + * we need to free dev_state outside the spinlock. + */ + list_for_each_entry_safe(dev_state, next, &freelist, list) { + list_del(&dev_state->list); + free_device_state(dev_state); + } + destroy_workqueue(iommu_wq); } |