summaryrefslogtreecommitdiff
path: root/drivers/bus
diff options
context:
space:
mode:
authorDavid Marchand <david.marchand@redhat.com>2019-07-22 14:56:51 +0200
committerThomas Monjalon <thomas@monjalon.net>2019-07-22 17:45:52 +0200
commitb76fafb174d2cd5247c3573bb3d49444e195e760 (patch)
treecdb2f1ac9bf344e0a35fa38d5d843b7e42d18410 /drivers/bus
parent62f8f5ace506b336afcb9022d4c456f893f1d732 (diff)
downloaddpdk-b76fafb174d2cd5247c3573bb3d49444e195e760.zip
dpdk-b76fafb174d2cd5247c3573bb3d49444e195e760.tar.gz
dpdk-b76fafb174d2cd5247c3573bb3d49444e195e760.tar.xz
eal: fix IOVA mode selection as VA for PCI drivers
The incriminated commit broke the use of RTE_PCI_DRV_IOVA_AS_VA which was intended to mean "driver only supports VA" but had been understood as "driver supports both PA and VA" by most net drivers and used to let dpdk processes to run as non root (which do not have access to physical addresses on recent kernels). The check on physical addresses actually closed the gap for those drivers. We don't need to mark them with RTE_PCI_DRV_IOVA_AS_VA and this flag can retain its intended meaning. Document explicitly its meaning. We can check that a driver requirement wrt to IOVA mode is fulfilled before trying to probe a device. Finally, document the heuristic used to select the IOVA mode and hope that we won't break it again. Fixes: 703458e19c16 ("bus/pci: consider only usable devices for IOVA mode") Signed-off-by: David Marchand <david.marchand@redhat.com> Reviewed-by: Jerin Jacob <jerinj@marvell.com> Tested-by: Jerin Jacob <jerinj@marvell.com> Acked-by: Anatoly Burakov <anatoly.burakov@intel.com>
Diffstat (limited to 'drivers/bus')
-rw-r--r--drivers/bus/pci/linux/pci.c16
-rw-r--r--drivers/bus/pci/pci_common.c30
-rw-r--r--drivers/bus/pci/rte_bus_pci.h4
3 files changed, 32 insertions, 18 deletions
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
index b12f10a..1a2f99b 100644
--- a/drivers/bus/pci/linux/pci.c
+++ b/drivers/bus/pci/linux/pci.c
@@ -578,12 +578,10 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,
else
is_vfio_noiommu_enabled = 0;
}
- if ((pdrv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) == 0) {
+ if (is_vfio_noiommu_enabled != 0)
iova_mode = RTE_IOVA_PA;
- } else if (is_vfio_noiommu_enabled != 0) {
- RTE_LOG(DEBUG, EAL, "Forcing to 'PA', vfio-noiommu mode configured\n");
- iova_mode = RTE_IOVA_PA;
- }
+ else if ((pdrv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) != 0)
+ iova_mode = RTE_IOVA_VA;
#endif
break;
}
@@ -594,8 +592,8 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,
break;
default:
- RTE_LOG(DEBUG, EAL, "Unsupported kernel driver? Defaulting to IOVA as 'PA'\n");
- iova_mode = RTE_IOVA_PA;
+ if ((pdrv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) != 0)
+ iova_mode = RTE_IOVA_VA;
break;
}
@@ -607,10 +605,8 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,
if (iommu_no_va == -1)
iommu_no_va = pci_one_device_iommu_support_va(pdev)
? 0 : 1;
- if (iommu_no_va != 0) {
- RTE_LOG(DEBUG, EAL, "Forcing to 'PA', IOMMU does not support IOVA as 'VA'\n");
+ 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 d2af472..9794552 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -169,8 +169,22 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
* This needs to be before rte_pci_map_device(), as it enables to use
* driver flags for adjusting configuration.
*/
- if (!already_probed)
+ if (!already_probed) {
+ enum rte_iova_mode dev_iova_mode;
+ enum rte_iova_mode iova_mode;
+
+ dev_iova_mode = pci_device_iova_mode(dr, dev);
+ iova_mode = rte_eal_iova_mode();
+ if (dev_iova_mode != RTE_IOVA_DC &&
+ dev_iova_mode != iova_mode) {
+ RTE_LOG(ERR, EAL, " Expecting '%s' IOVA mode but current mode is '%s', not initializing\n",
+ dev_iova_mode == RTE_IOVA_PA ? "PA" : "VA",
+ iova_mode == RTE_IOVA_PA ? "PA" : "VA");
+ return -EINVAL;
+ }
+
dev->driver = dr;
+ }
if (!already_probed && (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)) {
/* map resources for devices that use igb_uio */
@@ -629,12 +643,16 @@ rte_pci_get_iommu_class(void)
devices_want_va = true;
}
}
- if (devices_want_pa) {
- iova_mode = RTE_IOVA_PA;
- if (devices_want_va)
- RTE_LOG(WARNING, EAL, "Some devices want 'VA' but forcing 'PA' because other devices want it\n");
- } else if (devices_want_va) {
+ 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;
+ } else {
+ iova_mode = RTE_IOVA_DC;
+ if (devices_want_va) {
+ RTE_LOG(WARNING, EAL, "Some devices want 'VA' but forcing 'DC' because other devices want 'PA'.\n");
+ RTE_LOG(WARNING, EAL, "Depending on the final decision by the EAL, not all devices may be able to initialize.\n");
+ }
}
return iova_mode;
}
diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
index 06e004c..0f21775 100644
--- a/drivers/bus/pci/rte_bus_pci.h
+++ b/drivers/bus/pci/rte_bus_pci.h
@@ -187,8 +187,8 @@ struct rte_pci_bus {
#define RTE_PCI_DRV_INTR_RMV 0x0010
/** Device driver needs to keep mapped resources if unsupported dev detected */
#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
-/** Device driver supports IOVA as VA */
-#define RTE_PCI_DRV_IOVA_AS_VA 0X0040
+/** Device driver only supports IOVA as VA and cannot work with IOVA as PA */
+#define RTE_PCI_DRV_IOVA_AS_VA 0x0040
/**
* Map the PCI device resources in user space virtual memory address