X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=tools%2Fdpdk_nic_bind.py;h=8523f828024f7444f5784a2e580b82012bd62636;hb=1129992baa61d72c5;hp=e87a05ea8ba082311346578562e2121f7db3af99;hpb=f0e14c5f66c9c137b3e9ffea30acdcfdaa98b2af;p=dpdk.git diff --git a/tools/dpdk_nic_bind.py b/tools/dpdk_nic_bind.py index e87a05ea8b..8523f82802 100755 --- a/tools/dpdk_nic_bind.py +++ b/tools/dpdk_nic_bind.py @@ -42,6 +42,14 @@ ETHERNET_CLASS = "0200" # global dict ethernet devices present. Dictionary indexed by PCI address. # Each device within this is itself a dictionary of device properties devices = {} +# list of supported DPDK drivers +dpdk_drivers = [ "igb_uio", "vfio-pci", "uio_pci_generic" ] + +# command-line arg flags +b_flag = None +status_flag = False +force_flag = False +args = [] def usage(): '''Print usage information for the program''' @@ -146,21 +154,35 @@ def find_module(mod): def check_modules(): '''Checks that igb_uio is loaded''' + global dpdk_drivers fd = file("/proc/modules") loaded_mods = fd.readlines() fd.close() - mod = "igb_uio" + + # list of supported modules + mods = [{"Name" : driver, "Found" : False} for driver in dpdk_drivers] # first check if module is loaded - found = False for line in loaded_mods: - if line.startswith(mod): - found = True - break - if not found: - print "Error - module %s not loaded" %mod - sys.exit(1) + for mod in mods: + if line.startswith(mod["Name"]): + mod["Found"] = True + # special case for vfio_pci (module is named vfio-pci, + # but its .ko is named vfio_pci) + elif line.replace("_", "-").startswith(mod["Name"]): + mod["Found"] = True + + # check if we have at least one loaded module + if True not in [mod["Found"] for mod in mods] and b_flag is not None: + if b_flag in dpdk_drivers: + print "Error - no supported modules(DPDK driver) are loaded" + sys.exit(1) + else: + print "Warning - no supported modules(DPDK driver) are loaded" + + # change DPDK driver list to only contain drivers that are loaded + dpdk_drivers = [mod["Name"] for mod in mods if mod["Found"]] def has_driver(dev_id): '''return true if a device is assigned to a driver. False otherwise''' @@ -196,6 +218,7 @@ def get_nic_details(): the pci addresses (domain:bus:slot.func). The values are themselves dictionaries - one for each NIC.''' global devices + global dpdk_drivers # clear any old data devices = {} @@ -240,10 +263,11 @@ def get_nic_details(): # add igb_uio to list of supporting modules if needed if "Module_str" in devices[d]: - if "igb_uio" not in devices[d]["Module_str"]: - devices[d]["Module_str"] = devices[d]["Module_str"] + ",igb_uio" + for driver in dpdk_drivers: + if driver not in devices[d]["Module_str"]: + devices[d]["Module_str"] = devices[d]["Module_str"] + ",%s" % driver else: - devices[d]["Module_str"] = "igb_uio" + devices[d]["Module_str"] = ",".join(dpdk_drivers) # make sure the driver and module strings do not have any duplicates if has_driver(d): @@ -320,7 +344,7 @@ def bind_one(dev_id, driver, force): dev["Driver_str"] = "" # clear driver string # if we are binding to one of DPDK drivers, add PCI id's to that driver - if driver == "igb_uio": + if driver in dpdk_drivers: filename = "/sys/bus/pci/drivers/%s/new_id" % driver try: f = open(filename, "w") @@ -368,10 +392,31 @@ def unbind_all(dev_list, force=False): def bind_all(dev_list, driver, force=False): """Unbind method, takes a list of device locations""" + global devices + dev_list = map(dev_id_from_dev_name, dev_list) + for d in dev_list: bind_one(d, driver, force) + # when binding devices to a generic driver (i.e. one that doesn't have a + # PCI ID table), some devices that are not bound to any other driver could + # be bound even if no one has asked them to. hence, we check the list of + # drivers again, and see if some of the previously-unbound devices were + # erroneously bound. + for d in devices.keys(): + # skip devices that were already bound or that we know should be bound + if "Driver_str" in devices[d] or d in dev_list: + continue + + # update information about this device + devices[d] = dict(devices[d].items() + + get_pci_device_details(d).items()) + + # check if updated information indicates that the device was bound + if "Driver_str" in devices[d]: + unbind_one(d, force) + def display_devices(title, dev_list, extra_params = None): '''Displays to the user the details of a list of devices given in "dev_list" The "extra_params" parameter, if given, should contain a string with @@ -397,21 +442,23 @@ def show_status(): '''Function called when the script is passed the "--status" option. Displays to the user what devices are bound to the igb_uio driver, the kernel driver or to no driver''' + global dpdk_drivers kernel_drv = [] - uio_drv = [] + dpdk_drv = [] no_drv = [] + # split our list of devices into the three categories above for d in devices.keys(): if not has_driver(d): no_drv.append(devices[d]) continue - if devices[d]["Driver_str"] == "igb_uio": - uio_drv.append(devices[d]) + if devices[d]["Driver_str"] in dpdk_drivers: + dpdk_drv.append(devices[d]) else: kernel_drv.append(devices[d]) # print each category separately, so we can clearly see what's used by DPDK - display_devices("Network devices using IGB_UIO driver", uio_drv, \ + display_devices("Network devices using DPDK-compatible driver", dpdk_drv, \ "drv=%(Driver_str)s unused=%(Module_str)s") display_devices("Network devices using kernel driver", kernel_drv, "if=%(Interface)s drv=%(Driver_str)s unused=%(Module_str)s %(Active)s") @@ -421,9 +468,10 @@ def show_status(): def parse_args(): '''Parses the command-line arguments given by the user and takes the appropriate action for each''' - b_flag = None - status_flag = False - force_flag = False + global b_flag + global status_flag + global force_flag + global args if len(sys.argv) <= 1: usage() sys.exit(0) @@ -454,6 +502,13 @@ def parse_args(): else: b_flag = arg +def do_arg_actions(): + '''do the actual action requested by the user''' + global b_flag + global status_flag + global force_flag + global args + if b_flag is None and not status_flag: print "Error: No action specified for devices. Please give a -b or -u option" print "Run '%s --usage' for further information" % sys.argv[0] @@ -475,9 +530,10 @@ def parse_args(): def main(): '''program main function''' + parse_args() check_modules() get_nic_details() - parse_args() + do_arg_actions() if __name__ == "__main__": main()