Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iommu/amd: Tidy up DMA ops init

Now that DMA ops are part of the core API via iommu-dma, fold the
vestigial remains of the IOMMU_DMA_OPS init state into the IOMMU API
phase, and clean up a few other leftovers. This should also close the
race window wherein bus_set_iommu() effectively makes the DMA ops state
visible before its nominal initialisation - it seems this was previously
fairly benign, but since commit a250c23f15c2 ("iommu: remove
DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE") it can now lead to the strict flush
queue policy inadvertently being picked for default domains allocated
during that window, with a corresponding unexpected perfomance impact.

Reported-by: Jussi Maki <joamaki@gmail.com>
Tested-by: Jussi Maki <joamaki@gmail.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Fixes: a250c23f15c2 ("iommu: remove DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE")
Link: https://lore.kernel.org/r/665db61e23ff8d54ac5eb391bef520b3a803fcb9.1622727974.git.robin.murphy@arm.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>

authored by

Robin Murphy and committed by
Joerg Roedel
be227f8e 8124c8a6

+13 -25
-2
drivers/iommu/amd/amd_iommu.h
··· 11 11 12 12 #include "amd_iommu_types.h" 13 13 14 - extern int amd_iommu_init_dma_ops(void); 15 - extern int amd_iommu_init_passthrough(void); 16 14 extern irqreturn_t amd_iommu_int_thread(int irq, void *data); 17 15 extern irqreturn_t amd_iommu_int_handler(int irq, void *data); 18 16 extern void amd_iommu_apply_erratum_63(u16 devid);
-5
drivers/iommu/amd/init.c
··· 231 231 IOMMU_ENABLED, 232 232 IOMMU_PCI_INIT, 233 233 IOMMU_INTERRUPTS_EN, 234 - IOMMU_DMA_OPS, 235 234 IOMMU_INITIALIZED, 236 235 IOMMU_NOT_FOUND, 237 236 IOMMU_INIT_ERROR, ··· 2894 2895 init_state = ret ? IOMMU_INIT_ERROR : IOMMU_INTERRUPTS_EN; 2895 2896 break; 2896 2897 case IOMMU_INTERRUPTS_EN: 2897 - ret = amd_iommu_init_dma_ops(); 2898 - init_state = ret ? IOMMU_INIT_ERROR : IOMMU_DMA_OPS; 2899 - break; 2900 - case IOMMU_DMA_OPS: 2901 2898 init_state = IOMMU_INITIALIZED; 2902 2899 break; 2903 2900 case IOMMU_INITIALIZED:
+13 -18
drivers/iommu/amd/iommu.c
··· 30 30 #include <linux/msi.h> 31 31 #include <linux/irqdomain.h> 32 32 #include <linux/percpu.h> 33 - #include <linux/iova.h> 34 33 #include <linux/io-pgtable.h> 35 34 #include <asm/irq_remapping.h> 36 35 #include <asm/io_apic.h> ··· 1772 1773 amd_iommu_domain_flush_complete(domain); 1773 1774 } 1774 1775 1776 + static void __init amd_iommu_init_dma_ops(void) 1777 + { 1778 + swiotlb = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0; 1779 + 1780 + if (amd_iommu_unmap_flush) 1781 + pr_info("IO/TLB flush on unmap enabled\n"); 1782 + else 1783 + pr_info("Lazy IO/TLB flushing enabled\n"); 1784 + iommu_set_dma_strict(amd_iommu_unmap_flush); 1785 + } 1786 + 1775 1787 int __init amd_iommu_init_api(void) 1776 1788 { 1777 - int ret, err = 0; 1789 + int err = 0; 1778 1790 1779 - ret = iova_cache_get(); 1780 - if (ret) 1781 - return ret; 1791 + amd_iommu_init_dma_ops(); 1782 1792 1783 1793 err = bus_set_iommu(&pci_bus_type, &amd_iommu_ops); 1784 1794 if (err) ··· 1802 1794 return err; 1803 1795 1804 1796 return 0; 1805 - } 1806 - 1807 - int __init amd_iommu_init_dma_ops(void) 1808 - { 1809 - swiotlb = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0; 1810 - 1811 - if (amd_iommu_unmap_flush) 1812 - pr_info("IO/TLB flush on unmap enabled\n"); 1813 - else 1814 - pr_info("Lazy IO/TLB flushing enabled\n"); 1815 - iommu_set_dma_strict(amd_iommu_unmap_flush); 1816 - return 0; 1817 - 1818 1797 } 1819 1798 1820 1799 /*****************************************************************************