From 8415429e43cc8df6215d17ac150f75f483058c29 Mon Sep 17 00:00:00 2001 From: Bruce Richardson Date: Fri, 24 Mar 2017 14:30:11 +0000 Subject: [PATCH] nic_uio: fix device binding at boot 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") Cc: stable@dpdk.org Signed-off-by: Bruce Richardson --- lib/librte_eal/bsdapp/nic_uio/nic_uio.c | 44 +++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/lib/librte_eal/bsdapp/nic_uio/nic_uio.c b/lib/librte_eal/bsdapp/nic_uio/nic_uio.c index 99a4975c58..4bd7545a55 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 , -- 2.20.1