From 3a5670e8ac932c10a3e50d9dc0ab1da4cc3041d7 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Wed, 19 Feb 2014 14:07:33 +0800 Subject: iommu/vt-d: Introduce a rwsem to protect global data structures Introduce a global rwsem dmar_global_lock, which will be used to protect DMAR related global data structures from DMAR/PCI/memory device hotplug operations in process context. DMA and interrupt remapping related data structures are read most, and only change when memory/PCI/DMAR hotplug event happens. So a global rwsem solution is adopted for balance between simplicity and performance. For interrupt remapping driver, function intel_irq_remapping_supported(), dmar_table_init(), intel_enable_irq_remapping(), disable_irq_remapping(), reenable_irq_remapping() and enable_drhd_fault_handling() etc are called during booting, suspending and resuming with interrupt disabled, so no need to take the global lock. For interrupt remapping entry allocation, the locking model is: down_read(&dmar_global_lock); /* Find corresponding iommu */ iommu = map_hpet_to_ir(id); if (iommu) /* * Allocate remapping entry and mark entry busy, * the IOMMU won't be hot-removed until the * allocated entry has been released. */ index = alloc_irte(iommu, irq, 1); up_read(&dmar_global_lock); For DMA remmaping driver, we only uses the dmar_global_lock rwsem to protect functions which are only called in process context. For any function which may be called in interrupt context, we will use RCU to protect them in following patches. Signed-off-by: Jiang Liu Signed-off-by: Joerg Roedel --- include/linux/dmar.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/dmar.h') diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 4b77fd8fde76..8f06a0135a84 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -25,6 +25,7 @@ #include #include #include +#include struct acpi_dmar_header; @@ -48,6 +49,7 @@ struct dmar_drhd_unit { struct intel_iommu *iommu; }; +extern struct rw_semaphore dmar_global_lock; extern struct list_head dmar_drhd_units; #define for_each_drhd_unit(drhd) \ -- cgit v1.2.3