From c3ce205d5729867bd1c4c4429a80e01a528d5905 Mon Sep 17 00:00:00 2001 From: Guduri Prathyusha Date: Wed, 22 Mar 2017 19:41:28 +0530 Subject: [PATCH] usertools: optimize lspci invocation lspci invoked twice over all the pci devices in the system. The first pass is to extract Numeric IDs and second pass to get extended device details. As an optimization, Used lspci with -nn option in get_device_details() to obtain Numeric ID and extended device details in one shot. In addition to this, After binding the PCI device, lspci needs to be invoked again to confirm the proper bind operation. Used a boolean argument to express this case in get_pci_device_details() Signed-off-by: Guduri Prathyusha Signed-off-by: Jerin Jacob --- usertools/dpdk-devbind.py | 52 +++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py index 83c4c17c64..9beadde4ed 100755 --- a/usertools/dpdk-devbind.py +++ b/usertools/dpdk-devbind.py @@ -208,19 +208,20 @@ def has_driver(dev_id): return "Driver_str" in devices[dev_id] -def get_pci_device_details(dev_id): +def get_pci_device_details(dev_id, probe_lspci): '''This function gets additional details for a PCI device''' device = {} - extra_info = check_output(["lspci", "-vmmks", dev_id]).splitlines() + if probe_lspci: + extra_info = check_output(["lspci", "-vmmks", dev_id]).splitlines() - # parse lspci details - for line in extra_info: - if len(line) == 0: - continue - name, value = line.decode().split("\t", 1) - name = name.strip(":") + "_str" - device[name] = value + # parse lspci details + for line in extra_info: + if len(line) == 0: + continue + name, value = line.decode().split("\t", 1) + name = name.strip(":") + "_str" + device[name] = value # check for a unix interface name device["Interface"] = "" for base, dirs, _ in os.walk("/sys/bus/pci/devices/%s/" % dev_id): @@ -246,20 +247,30 @@ def get_device_details(devices_type): global dpdk_drivers # first loop through and read details for all devices - # request machine readable format, with numeric IDs + # request machine readable format, with numeric IDs and String dev = {} - dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines() + dev_lines = check_output(["lspci", "-Dvmmnnk"]).splitlines() for dev_line in dev_lines: if len(dev_line) == 0: if dev["Class"][0:2] == devices_type: # convert device and vendor ids to numbers, then add to global dev["Vendor"] = int(dev["Vendor"], 16) dev["Device"] = int(dev["Device"], 16) + if "Driver" in dev.keys(): + dev["Driver_str"] = dev.pop("Driver") # use dict to make copy of dev devices[dev["Slot"]] = dict(dev) + # Clear previous device's data + dev = {} else: name, value = dev_line.decode().split("\t", 1) - dev[name.rstrip(":")] = value + value_list = value.rsplit(' ', 1) + if len(value_list) > 1: + # String stored in _str + dev[name.rstrip(":") + '_str'] = value_list[0] + # Numeric IDs + dev[name.rstrip(":")] = value_list[len(value_list) - 1] \ + .rstrip("]").lstrip("[") if devices_type == NETWORK_BASE_CLASS: # check what is the interface if any for an ssh connection if @@ -281,7 +292,8 @@ def get_device_details(devices_type): # get additional info and add it to existing data devices[d] = devices[d].copy() - devices[d].update(get_pci_device_details(d).items()) + # No need to probe lspci + devices[d].update(get_pci_device_details(d, False).items()) if devices_type == NETWORK_BASE_CLASS: for _if in ssh_if: @@ -412,7 +424,7 @@ def bind_one(dev_id, driver, force): # for some reason, closing dev_id after adding a new PCI ID to new_id # results in IOError. however, if the device was successfully bound, # we don't care for any errors and can safely ignore IOError - tmp = get_pci_device_details(dev_id) + tmp = get_pci_device_details(dev_id, True) if "Driver_str" in tmp and tmp["Driver_str"] == driver: return print("Error: bind failed for %s - Cannot bind to driver %s" @@ -450,7 +462,7 @@ def bind_all(dev_list, driver, force=False): # update information about this device devices[d] = dict(devices[d].items() + - get_pci_device_details(d).items()) + get_pci_device_details(d, True).items()) # check if updated information indicates that the device was bound if "Driver_str" in devices[d]: @@ -470,8 +482,9 @@ def display_devices(title, dev_list, extra_params=None): else: for dev in dev_list: if extra_params is not None: - strings.append("%s '%s' %s" % (dev["Slot"], + strings.append("%s '%s %s' %s" % (dev["Slot"], dev["Device_str"], + dev["Device"], extra_params % dev)) else: strings.append("%s '%s'" % (dev["Slot"], dev["Device_str"])) @@ -497,12 +510,13 @@ def show_device_status(devices_type, device_name): kernel_drv.append(devices[d]) # print each category separately, so we can clearly see what's used by DPDK - display_devices("%s devices using DPDK-compatible driver" % device_name, dpdk_drv, - "drv=%(Driver_str)s unused=%(Module_str)s") + display_devices("%s devices using DPDK-compatible driver" % device_name, + dpdk_drv, "drv=%(Driver_str)s unused=%(Module_str)s") display_devices("%s devices using kernel driver" % device_name, kernel_drv, "if=%(Interface)s drv=%(Driver_str)s " "unused=%(Module_str)s %(Active)s") - display_devices("Other %s devices" % device_name, no_drv, "unused=%(Module_str)s") + display_devices("Other %s devices" % device_name, no_drv, + "unused=%(Module_str)s") def show_status(): '''Function called when the script is passed the "--status" option. -- 2.20.1