[dpdk-dev,v2,4/7] pci: rte_eal_pci_scan now handles removal of PCI devices

Message ID 1479931644-78960-4-git-send-email-benjamin.walker@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers

Checks

Context Check Description
checkpatch/checkpatch warning coding style issues

Commit Message

Walker, Benjamin Nov. 23, 2016, 8:07 p.m. UTC
  rte_eal_pci_scan can be called repeatedly to re-scan the PCI
bus. If a device was removed from the system, the associated
driver will automatically be unloaded.

Signed-off-by: Ben Walker <benjamin.walker@intel.com>
---
 lib/librte_eal/linuxapp/eal/eal_pci.c | 62 +++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)
  

Comments

Shreyansh Jain Nov. 25, 2016, 10:44 a.m. UTC | #1
Hi Ben,

On Thursday 24 November 2016 01:37 AM, Ben Walker wrote:
> rte_eal_pci_scan can be called repeatedly to re-scan the PCI
> bus. If a device was removed from the system, the associated
> driver will automatically be unloaded.
>
> Signed-off-by: Ben Walker <benjamin.walker@intel.com>
> ---
[...]

While reviewing, I found that there are some checkpatch warnings on this 
patch:

--->8---
### [PATCH v2 4/7] pci: rte_eal_pci_scan now handles removal of PCI devices

WARNING:LONG_LINE_COMMENT: line over 80 characters
#76: FILE: lib/librte_eal/linuxapp/eal/eal_pci.c:490:
+       /* Search the device list for devices that are no longer present 
on the system

WARNING:LONG_LINE_STRING: line over 80 characters
#105: FILE: lib/librte_eal/linuxapp/eal/eal_pci.c:519:
+                       RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" 
was removed.\n",

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a 
separate line
#111: FILE: lib/librte_eal/linuxapp/eal/eal_pci.c:525:
+                                * Unload it. */

WARNING:LONG_LINE_STRING: line over 80 characters
#112: FILE: lib/librte_eal/linuxapp/eal/eal_pci.c:526:
+                               RTE_LOG(DEBUG, EAL, "  Unload driver: 
%x:%x %s\n",

WARNING:LONG_LINE: line over 80 characters
#113: FILE: lib/librte_eal/linuxapp/eal/eal_pci.c:527:
+                                               dev->id.vendor_id, 
dev->id.device_id,

WARNING:LONG_LINE_COMMENT: line over 80 characters
#117: FILE: lib/librte_eal/linuxapp/eal/eal_pci.c:531:
+                                       /* It doesn't matter what remove 
returns -

WARNING:LONG_LINE_COMMENT: line over 80 characters
#118: FILE: lib/librte_eal/linuxapp/eal/eal_pci.c:532:
+                                        * we're removing the device 
either way. */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a 
separate line
#118: FILE: lib/librte_eal/linuxapp/eal/eal_pci.c:532:
+                                        * we're removing the device 
either way. */

WARNING:LONG_LINE: line over 80 characters
#125: FILE: lib/librte_eal/linuxapp/eal/eal_pci.c:539:
+                               if (dev->driver->drv_flags & 
RTE_PCI_DRV_NEED_MAPPING)

total: 0 errors, 9 warnings, 69 lines checked

--->8---
  

Patch

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 073af5f..936f076 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -485,7 +485,69 @@  rte_eal_pci_scan(void)
 	DIR *dir;
 	char dirname[PATH_MAX];
 	struct rte_pci_addr addr;
+	struct rte_pci_device *dev, *tmp;
+
+	/* Search the device list for devices that are no longer present on the system
+	 * and remove them.
+	 */
+	TAILQ_FOREACH_SAFE(dev, &pci_device_list, next, tmp) {
+		int found = 0;
+
+		dir = opendir(pci_get_sysfs_path());
+		if (dir == NULL) {
+			RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+				__func__, strerror(errno));
+			return -1;
+		}
+
+		while ((e = readdir(dir)) != NULL) {
+			if (e->d_name[0] == '.')
+				continue;
+
+			if (parse_pci_addr_format(e->d_name, sizeof(e->d_name),
+						  &addr) != 0)
+				continue;
+
+			if (rte_eal_compare_pci_addr(&addr, &dev->addr) == 0) {
+				found = 1;
+				break;
+			}
+		}
+
+		if (!found) {
+
+			RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" was removed.\n",
+					addr.domain, addr.bus, addr.devid,
+					addr.function);
+
+			if (dev->driver) {
+				/* A driver was loaded against this device.
+				 * Unload it. */
+				RTE_LOG(DEBUG, EAL, "  Unload driver: %x:%x %s\n",
+						dev->id.vendor_id, dev->id.device_id,
+						dev->driver->driver.name);
+
+				if (dev->driver->remove) {
+					/* It doesn't matter what remove returns -
+					 * we're removing the device either way. */
+					dev->driver->remove(dev);
+				}
+
+				/* clear driver structure */
+				dev->driver = NULL;
+
+				if (dev->driver->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+					rte_eal_pci_unmap_device(dev);
+			}
+
+			TAILQ_REMOVE(&pci_device_list, dev, next);
+			free(dev);
+		}
+
+		closedir(dir);
+	}
 
+	/* Search sysfs for all PCI devices and add them to the device list */
 	dir = opendir(pci_get_sysfs_path());
 	if (dir == NULL) {
 		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",