[dpdk-dev] eal/bsdapp: fix device binding at boot

Message ID 20170324143011.29279-1-bruce.richardson@intel.com (mailing list archive)
State Accepted, archived
Delegated to: Thomas Monjalon
Headers

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK

Commit Message

Bruce Richardson March 24, 2017, 2:30 p.m. UTC
  When loading nic_uio from /boot/loader.conf as specified in the Getting
Started Guide doc, the NIC devices were not bound at boot. Unloading the
nic_uio driver and reloading it would cause them to be bound, however.

The root cause appears to be the fact that when the module is loaded at
boot, the call to find the pci device when parsing the b:d:f parameter
fails to return the device. That means that later on when the device
is probed as part of a PCI scan, no action is taken as it's not recorded
as a device to be used.

We fix this by having the b:d:f string parsed again on probe if the
initial check to see if it's an already-known device fails. In my tests,
this causes the NIC devices to be successfully bound at boot time, as
well as leaving things working as before in the case the module is loaded
post-boot.

Fixes: 764bf26873b9 ("add FreeBSD support")

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 lib/librte_eal/bsdapp/nic_uio/nic_uio.c | 44 +++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)
  

Comments

Thomas Monjalon April 4, 2017, 10:27 a.m. UTC | #1
2017-03-24 14:30, Bruce Richardson:
> When loading nic_uio from /boot/loader.conf as specified in the Getting
> Started Guide doc, the NIC devices were not bound at boot. Unloading the
> nic_uio driver and reloading it would cause them to be bound, however.
> 
> The root cause appears to be the fact that when the module is loaded at
> boot, the call to find the pci device when parsing the b:d:f parameter
> fails to return the device. That means that later on when the device
> is probed as part of a PCI scan, no action is taken as it's not recorded
> as a device to be used.
> 
> We fix this by having the b:d:f string parsed again on probe if the
> initial check to see if it's an already-known device fails. In my tests,
> this causes the NIC devices to be successfully bound at boot time, as
> well as leaving things working as before in the case the module is loaded
> post-boot.
> 
> Fixes: 764bf26873b9 ("add FreeBSD support")
> 
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>

Cc: stable@dpdk.org

Applied, thanks
  

Patch

diff --git a/lib/librte_eal/bsdapp/nic_uio/nic_uio.c b/lib/librte_eal/bsdapp/nic_uio/nic_uio.c
index 99a4975c5..4bd7545a5 100644
--- a/lib/librte_eal/bsdapp/nic_uio/nic_uio.c
+++ b/lib/librte_eal/bsdapp/nic_uio/nic_uio.c
@@ -180,6 +180,10 @@  nic_uio_probe (device_t dev)
 	unsigned int device = pci_get_slot(dev);
 	unsigned int function = pci_get_function(dev);
 
+	char bdf_str[256];
+	char *token, *remaining;
+
+	/* First check if we found this on load */
 	for (i = 0; i < num_detached; i++)
 		if (bus == pci_get_bus(detached_devices[i]) &&
 		    device == pci_get_slot(detached_devices[i]) &&
@@ -188,6 +192,45 @@  nic_uio_probe (device_t dev)
 			return BUS_PROBE_SPECIFIC;
 		}
 
+	/* otherwise check if it's a new device and if it matches the BDF */
+	memset(bdf_str, 0, sizeof(bdf_str));
+	TUNABLE_STR_FETCH("hw.nic_uio.bdfs", bdf_str, sizeof(bdf_str));
+	remaining = bdf_str;
+	while (1) {
+		if (remaining == NULL || remaining[0] == '\0')
+			break;
+		token = strsep(&remaining, ",:");
+		if (token == NULL)
+			break;
+		bus = strtol(token, NULL, 10);
+		token = strsep(&remaining, ",:");
+		if (token == NULL)
+			break;
+		device = strtol(token, NULL, 10);
+		token = strsep(&remaining, ",:");
+		if (token == NULL)
+			break;
+		function = strtol(token, NULL, 10);
+
+		if (bus == pci_get_bus(dev) &&
+				device == pci_get_slot(dev) &&
+				function == pci_get_function(dev)) {
+
+			if (num_detached < MAX_DETACHED_DEVICES) {
+				printf("%s: probed dev=%p\n",
+					       __func__, dev);
+				detached_devices[num_detached++] = dev;
+				device_set_desc(dev, "DPDK PCI Device");
+				return BUS_PROBE_SPECIFIC;
+			} else {
+				printf("%s: reached MAX_DETACHED_DEVICES=%d. dev=%p won't be reattached\n",
+						__func__, MAX_DETACHED_DEVICES,
+						dev);
+				break;
+			}
+		}
+	}
+
 	return ENXIO;
 }
 
@@ -248,6 +291,7 @@  nic_uio_load(void)
 	memset(bdf_str, 0, sizeof(bdf_str));
 	TUNABLE_STR_FETCH("hw.nic_uio.bdfs", bdf_str, sizeof(bdf_str));
 	remaining = bdf_str;
+	printf("nic_uio: hw.nic_uio.bdfs = '%s'\n", bdf_str);
 	/*
 	 * Users should specify PCI BDFs in the format "b:d:f,b:d:f,b:d:f".
 	 *  But the code below does not try differentiate between : and ,