-----Original Message-----
From: Guo, Jia
Sent: Friday, April 6, 2018 11:57 AM
To: step...@networkplumber.org; Richardson, Bruce <bruce.richard...@intel.com>;
Yigit, Ferruh <ferruh.yi...@intel.com>; Ananyev,
Konstantin <konstantin.anan...@intel.com>; gaetan.ri...@6wind.com; Wu, Jingjing
<jingjing...@intel.com>; tho...@monjalon.net;
mo...@mellanox.com; Van Haaren, Harry <harry.van.haa...@intel.com>; Tan, Jianfeng
<jianfeng....@intel.com>
Cc: jblu...@infradead.org; shreyansh.j...@nxp.com; dev@dpdk.org; Guo, Jia
<jia....@intel.com>; Zhang, Helin <helin.zh...@intel.com>
Subject: [PATCH V19 1/4] bus/pci: introduce device hot unplug handle
As of device hot unplug, we need some preparatory measures so that we will
not encounter memory fault after device be plug out of the system,
and also let we could recover the running data path but not been break.
This allows the buses to handle device hot unplug event.
The patch only enable the ops in pci bus, when handle device hot unplug
event, remap a dummy memory to avoid bus read/write error.
Other buses could accordingly implement this ops specific by themselves.
Signed-off-by: Jeff Guo <jia....@intel.com>
---
v19->v18:
fix some typo and squeeze patch
---
drivers/bus/pci/pci_common.c | 42 +++++++++++++++++++++++++++++++++
drivers/bus/pci/pci_common_uio.c | 32 +++++++++++++++++++++++++
drivers/bus/pci/private.h | 12 ++++++++++
lib/librte_eal/common/include/rte_bus.h | 15 ++++++++++++
4 files changed, 101 insertions(+)
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 2a00f36..09192ed 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -474,6 +474,47 @@ pci_find_device(const struct rte_device *start,
rte_dev_cmp_t cmp,
}
static int
+pci_handle_hot_unplug(struct rte_device *dev)
+{
+ struct rte_pci_device *pdev;
+ int ret;
+
+ if (dev == NULL)
+ return -EINVAL;
+
+ pdev = RTE_DEV_TO_PCI(dev);
+
+ /* remap resources for devices */
+ switch (pdev->kdrv) {
+ case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+ /* TODO */
+#endif
+ break;
+ case RTE_KDRV_IGB_UIO:
+ case RTE_KDRV_UIO_GENERIC:
+ if (rte_eal_using_phys_addrs()) {
+ /* map resources for devices that use uio */
+ ret = pci_uio_remap_resource(pdev);
+ }
+ break;
+ case RTE_KDRV_NIC_UIO:
+ ret = pci_uio_remap_resource(pdev);
+ break;
+ default:
+ RTE_LOG(DEBUG, EAL,
+ " Not managed by a supported kernel driver,
skipped\n");
+ ret = -1;
+ break;
+ }
+
+ if (ret != 0)
+ RTE_LOG(ERR, EAL, "failed to handle hot unplug of %s",
+ pdev->name);
+ return ret;
+}
+
+static int
pci_plug(struct rte_device *dev)
{
return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
@@ -503,6 +544,7 @@ struct rte_pci_bus rte_pci_bus = {
.unplug = pci_unplug,
.parse = pci_parse,
.get_iommu_class = rte_pci_get_iommu_class,
+ .handle_hot_unplug = pci_handle_hot_unplug,
},
.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
diff --git a/drivers/bus/pci/pci_common_uio.c b/drivers/bus/pci/pci_common_uio.c
index 54bc20b..31a4094 100644
--- a/drivers/bus/pci/pci_common_uio.c
+++ b/drivers/bus/pci/pci_common_uio.c
@@ -146,6 +146,38 @@ pci_uio_unmap(struct mapped_pci_resource *uio_res)
}
}
+/* remap the PCI resource of a PCI device in private virtual memory */
+int
+pci_uio_remap_resource(struct rte_pci_device *dev)
+{
+ int i;
+ void *map_address;
+
+ if (dev == NULL)
+ return -1;
+
+ /* Remap all BARs */
+ for (i = 0; i != PCI_MAX_RESOURCE; i++) {
+ /* skip empty BAR */
+ if (dev->mem_resource[i].phys_addr == 0)
+ continue;
+ pci_unmap_resource(dev->mem_resource[i].addr,
+ (size_t)dev->mem_resource[i].len);
+ map_address = pci_map_resource(
+ dev->mem_resource[i].addr, -1, 0,
+ (size_t)dev->mem_resource[i].len,
+ MAP_ANONYMOUS | MAP_FIXED);