-----David Marchand <david.march...@redhat.com> wrote: ----- >To: dev@dpdk.org >From: David Marchand <david.march...@redhat.com> >Date: 08/02/2019 07:14PM >Cc: anatoly.bura...@intel.com, t...@jp.ibm.com, >d...@linux.vnet.ibm.com >Subject: [PATCH] bus/pci: always check IOMMU capabilities > >IOMMU capabilities won't change and must be checked even if no PCI >device >seem to be supported yet when EAL initialised. > >This is to accommodate with SPDK that registers its drivers after >rte_eal_init(), especially on PPC platform where the IOMMU does not >support VA. > >Fixes: 703458e19c16 ("bus/pci: consider only usable devices for IOVA >mode") > >Signed-off-by: David Marchand <david.march...@redhat.com> >--- > drivers/bus/pci/bsd/pci.c | 6 ++++++ > drivers/bus/pci/linux/pci.c | 25 ++++++------------------- > drivers/bus/pci/pci_common.c | 16 +++++++++++++++- > drivers/bus/pci/private.h | 5 ++++- > 4 files changed, 31 insertions(+), 21 deletions(-) > >diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c >index a2de709..8f07ed9 100644 >--- a/drivers/bus/pci/bsd/pci.c >+++ b/drivers/bus/pci/bsd/pci.c >@@ -376,6 +376,12 @@ error: > return -1; > } > >+bool >+pci_device_iommu_support_va(__rte_unused const struct rte_pci_device >*dev) >+{ >+ return false; >+} >+ > enum rte_iova_mode > pci_device_iova_mode(const struct rte_pci_driver *pdrv __rte_unused, > const struct rte_pci_device *pdev) >diff --git a/drivers/bus/pci/linux/pci.c >b/drivers/bus/pci/linux/pci.c >index f4fb742..43debaa 100644 >--- a/drivers/bus/pci/linux/pci.c >+++ b/drivers/bus/pci/linux/pci.c >@@ -498,8 +498,8 @@ error: > } > > #if defined(RTE_ARCH_X86) >-static bool >-pci_one_device_iommu_support_va(const struct rte_pci_device *dev) >+bool >+pci_device_iommu_support_va(const struct rte_pci_device *dev) > { > #define VTD_CAP_MGAW_SHIFT 16 > #define VTD_CAP_MGAW_MASK (0x3fULL << VTD_CAP_MGAW_SHIFT) >@@ -546,14 +546,14 @@ pci_one_device_iommu_support_va(const struct >rte_pci_device *dev) > return true; > } > #elif defined(RTE_ARCH_PPC_64) >-static bool >-pci_one_device_iommu_support_va(__rte_unused const struct >rte_pci_device *dev) >+bool >+pci_device_iommu_support_va(__rte_unused const struct rte_pci_device >*dev) > { > return false; > } > #else >-static bool >-pci_one_device_iommu_support_va(__rte_unused const struct >rte_pci_device *dev) >+bool >+pci_device_iommu_support_va(__rte_unused const struct rte_pci_device >*dev) > { > return true; > } >@@ -564,7 +564,6 @@ pci_device_iova_mode(const struct rte_pci_driver >*pdrv, > const struct rte_pci_device *pdev) > { > enum rte_iova_mode iova_mode = RTE_IOVA_DC; >- static int iommu_no_va = -1; > > switch (pdev->kdrv) { > case RTE_KDRV_VFIO: { >@@ -595,18 +594,6 @@ pci_device_iova_mode(const struct rte_pci_driver >*pdrv, > iova_mode = RTE_IOVA_VA; > break; > } >- >- if (iova_mode != RTE_IOVA_PA) { >- /* >- * We can check this only once, because the IOMMU hardware is >- * the same for all of them. >- */ >- if (iommu_no_va == -1) >- iommu_no_va = pci_one_device_iommu_support_va(pdev) >- ? 0 : 1; >- if (iommu_no_va != 0) >- iova_mode = RTE_IOVA_PA; >- } > return iova_mode; > } > >diff --git a/drivers/bus/pci/pci_common.c >b/drivers/bus/pci/pci_common.c >index 9794552..8d1d6ab 100644 >--- a/drivers/bus/pci/pci_common.c >+++ b/drivers/bus/pci/pci_common.c >@@ -616,8 +616,16 @@ rte_pci_get_iommu_class(void) > const struct rte_pci_driver *drv; > bool devices_want_va = false; > bool devices_want_pa = false; >+ static int iommu_no_va = -1; > > FOREACH_DEVICE_ON_PCIBUS(dev) { >+ /* >+ * We can check this only once, because the IOMMU hardware is >+ * the same for all of them. >+ */ >+ if (iommu_no_va == -1) >+ iommu_no_va = pci_device_iommu_support_va(dev) >+ ? 0 : 1; > if (pci_ignore_device(dev)) > continue; > if (dev->kdrv == RTE_KDRV_UNKNOWN || >@@ -643,7 +651,13 @@ rte_pci_get_iommu_class(void) > devices_want_va = true; > } > } >- if (devices_want_va && !devices_want_pa) { >+ if (iommu_no_va == 1) { >+ iova_mode = RTE_IOVA_PA; >+ if (devices_want_va) { >+ RTE_LOG(WARNING, EAL, "Some devices want 'VA' but >because IOMMU >does not support 'VA'.\n"); >+ RTE_LOG(WARNING, EAL, "The devices that want 'VA' won't >initialize.\n"); >+ } >+ } else if (devices_want_va && !devices_want_pa) { > iova_mode = RTE_IOVA_VA; > } else if (devices_want_pa && !devices_want_va) { > iova_mode = RTE_IOVA_PA; >diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h >index 8a55240..a205d4d 100644 >--- a/drivers/bus/pci/private.h >+++ b/drivers/bus/pci/private.h >@@ -173,9 +173,12 @@ rte_pci_match(const struct rte_pci_driver >*pci_drv, > const struct rte_pci_device *pci_dev); > > /** >- * OS specific callback for rte_pci_get_iommu_class >+ * OS specific callbacks for rte_pci_get_iommu_class > * > */ >+bool >+pci_device_iommu_support_va(const struct rte_pci_device *dev); >+ > enum rte_iova_mode > pci_device_iova_mode(const struct rte_pci_driver *pci_drv, > const struct rte_pci_device *pci_dev); >-- >1.8.3.1 > >
Tested-by: Takeshi Yoshimura <t...@jp.ibm.com>