iommu/vt-d: Introduce a rwsem to protect global data structures
authorJiang Liu <jiang.liu@linux.intel.com>
Wed, 19 Feb 2014 06:07:33 +0000 (14:07 +0800)
committerJoerg Roedel <joro@8bytes.org>
Tue, 4 Mar 2014 16:51:05 +0000 (17:51 +0100)
commit3a5670e8ac932c10a3e50d9dc0ab1da4cc3041d7
tree83a870c5951c2deafcf7eef4fc2212bb937f1b6e
parentb683b230a244c3b2b3f6f3292e59d4a63298528b
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 <jiang.liu@linux.intel.com>
Signed-off-by: Joerg Roedel <joro@8bytes.org>
drivers/iommu/dmar.c
drivers/iommu/intel-iommu.c
drivers/iommu/intel_irq_remapping.c
include/linux/dmar.h