Skip to content

Commit d74169c

Browse files
Dimitri Sivanichjoergroedel
Dimitri Sivanich
authored andcommitted
iommu/vt-d: Allocate DMAR fault interrupts locally
The Intel IOMMU code currently tries to allocate all DMAR fault interrupt vectors on the boot cpu. On large systems with high DMAR counts this results in vector exhaustion, and most of the vectors are not initially allocated socket local. Instead, have a cpu on each node do the vector allocation for the DMARs on that node. The boot cpu still does the allocation for its node during its boot sequence. Signed-off-by: Dimitri Sivanich <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Lu Baolu <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent 9e7ee0f commit d74169c

File tree

6 files changed

+15
-7
lines changed

6 files changed

+15
-7
lines changed

drivers/iommu/amd/amd_iommu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ int amd_iommu_prepare(void);
3333
int amd_iommu_enable(void);
3434
void amd_iommu_disable(void);
3535
int amd_iommu_reenable(int mode);
36-
int amd_iommu_enable_faulting(void);
36+
int amd_iommu_enable_faulting(unsigned int cpu);
3737
extern int amd_iommu_guest_ir;
3838
extern enum io_pgtable_fmt amd_iommu_pgtable;
3939
extern int amd_iommu_gpt_level;

drivers/iommu/amd/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3392,7 +3392,7 @@ int amd_iommu_reenable(int mode)
33923392
return 0;
33933393
}
33943394

3395-
int __init amd_iommu_enable_faulting(void)
3395+
int __init amd_iommu_enable_faulting(unsigned int cpu)
33963396
{
33973397
/* We enable MSI later when PCI is initialized */
33983398
return 0;

drivers/iommu/intel/dmar.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2121,7 +2121,7 @@ int dmar_set_interrupt(struct intel_iommu *iommu)
21212121
return ret;
21222122
}
21232123

2124-
int __init enable_drhd_fault_handling(void)
2124+
int enable_drhd_fault_handling(unsigned int cpu)
21252125
{
21262126
struct dmar_drhd_unit *drhd;
21272127
struct intel_iommu *iommu;
@@ -2131,7 +2131,12 @@ int __init enable_drhd_fault_handling(void)
21312131
*/
21322132
for_each_iommu(iommu, drhd) {
21332133
u32 fault_status;
2134-
int ret = dmar_set_interrupt(iommu);
2134+
int ret;
2135+
2136+
if (iommu->irq || iommu->node != cpu_to_node(cpu))
2137+
continue;
2138+
2139+
ret = dmar_set_interrupt(iommu);
21352140

21362141
if (ret) {
21372142
pr_err("DRHD %Lx: failed to enable fault, interrupt, ret %d\n",

drivers/iommu/irq_remapping.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,10 @@ int __init irq_remap_enable_fault_handling(void)
151151
if (!remap_ops->enable_faulting)
152152
return -ENODEV;
153153

154-
return remap_ops->enable_faulting();
154+
cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "dmar:enable_fault_handling",
155+
remap_ops->enable_faulting, NULL);
156+
157+
return remap_ops->enable_faulting(smp_processor_id());
155158
}
156159

157160
void panic_if_irq_remap(const char *msg)

drivers/iommu/irq_remapping.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ struct irq_remap_ops {
4141
int (*reenable)(int);
4242

4343
/* Enable fault handling */
44-
int (*enable_faulting)(void);
44+
int (*enable_faulting)(unsigned int);
4545
};
4646

4747
extern struct irq_remap_ops intel_irq_remap_ops;

include/linux/dmar.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ extern int dmar_remove_dev_scope(struct dmar_pci_notify_info *info,
117117
int count);
118118
/* Intel IOMMU detection */
119119
void detect_intel_iommu(void);
120-
extern int enable_drhd_fault_handling(void);
120+
extern int enable_drhd_fault_handling(unsigned int cpu);
121121
extern int dmar_device_add(acpi_handle handle);
122122
extern int dmar_device_remove(acpi_handle handle);
123123

0 commit comments

Comments
 (0)