Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/41486/?format=api
http://patches.dpdk.org/api/patches/41486/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/043ece6a03f80934b2c35aab76936d591dd2e25d.1529940601.git.anatoly.burakov@intel.com/", "project": { "id": 1, "url": "http://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<043ece6a03f80934b2c35aab76936d591dd2e25d.1529940601.git.anatoly.burakov@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dev/043ece6a03f80934b2c35aab76936d591dd2e25d.1529940601.git.anatoly.burakov@intel.com", "date": "2018-06-25T15:59:43", "name": "[RFC,6/9] usertools/devbind: switch to using DPDKConfigLib", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "09e3a39e4512b1615c91d1d9e0c1dc563a0fc1f6", "submitter": { "id": 4, "url": "http://patches.dpdk.org/api/people/4/?format=api", "name": "Anatoly Burakov", "email": "anatoly.burakov@intel.com" }, "delegate": { "id": 1, "url": "http://patches.dpdk.org/api/users/1/?format=api", "username": "tmonjalo", "first_name": "Thomas", "last_name": "Monjalon", "email": "thomas@monjalon.net" }, "mbox": "http://patches.dpdk.org/project/dpdk/patch/043ece6a03f80934b2c35aab76936d591dd2e25d.1529940601.git.anatoly.burakov@intel.com/mbox/", "series": [ { "id": 225, "url": "http://patches.dpdk.org/api/series/225/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=225", "date": "2018-06-25T15:59:39", "name": "Modularize and enhance DPDK Python scripts", "version": 1, "mbox": "http://patches.dpdk.org/series/225/mbox/" } ], "comments": "http://patches.dpdk.org/api/patches/41486/comments/", "check": "fail", "checks": "http://patches.dpdk.org/api/patches/41486/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@dpdk.org", "Delivered-To": "patchwork@dpdk.org", "Received": [ "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 2F05B5920;\n\tMon, 25 Jun 2018 18:00:07 +0200 (CEST)", "from mga17.intel.com (mga17.intel.com [192.55.52.151])\n\tby dpdk.org (Postfix) with ESMTP id 47F6D1559\n\tfor <dev@dpdk.org>; Mon, 25 Jun 2018 17:59:53 +0200 (CEST)", "from orsmga003.jf.intel.com ([10.7.209.27])\n\tby fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t25 Jun 2018 08:59:50 -0700", "from irvmail001.ir.intel.com ([163.33.26.43])\n\tby orsmga003.jf.intel.com with ESMTP; 25 Jun 2018 08:59:47 -0700", "from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com\n\t[10.237.217.45])\n\tby irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id\n\tw5PFxlcx032515; Mon, 25 Jun 2018 16:59:47 +0100", "from sivswdev01.ir.intel.com (localhost [127.0.0.1])\n\tby sivswdev01.ir.intel.com with ESMTP id w5PFxlWl026627;\n\tMon, 25 Jun 2018 16:59:47 +0100", "(from aburakov@localhost)\n\tby sivswdev01.ir.intel.com with LOCAL id w5PFxlUD026615;\n\tMon, 25 Jun 2018 16:59:47 +0100" ], "X-Amp-Result": "SKIPPED(no attachment in message)", "X-Amp-File-Uploaded": "False", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.51,270,1526367600\"; d=\"scan'208\";a=\"62046254\"", "From": "Anatoly Burakov <anatoly.burakov@intel.com>", "To": "dev@dpdk.org", "Cc": "john.mcnamara@intel.com, bruce.richardson@intel.com,\n\tpablo.de.lara.guarch@intel.com, david.hunt@intel.com,\n\tmohammad.abdul.awal@intel.com", "Date": "Mon, 25 Jun 2018 16:59:43 +0100", "Message-Id": "<043ece6a03f80934b2c35aab76936d591dd2e25d.1529940601.git.anatoly.burakov@intel.com>", "X-Mailer": "git-send-email 1.7.0.7", "In-Reply-To": [ "<cover.1529940601.git.anatoly.burakov@intel.com>", "<cover.1529940601.git.anatoly.burakov@intel.com>" ], "References": [ "<cover.1529940601.git.anatoly.burakov@intel.com>", "<cover.1529940601.git.anatoly.burakov@intel.com>" ], "Subject": "[dpdk-dev] [RFC 6/9] usertools/devbind: switch to using\n\tDPDKConfigLib", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "Make devbind use DPDKConfigLib library instead of having its own\nlogic for binding/unbinding/enumerating devices and getting\ndevice information.\n\nAll semantics and output are kept the same, only the internals\nchanged.\n\nSigned-off-by: Anatoly Burakov <anatoly.burakov@intel.com>\n---\n usertools/dpdk-devbind.py | 518 ++++++--------------------------------\n 1 file changed, 70 insertions(+), 448 deletions(-)", "diff": "diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py\nindex d0c420906..7baddb622 100755\n--- a/usertools/dpdk-devbind.py\n+++ b/usertools/dpdk-devbind.py\n@@ -1,47 +1,18 @@\n #! /usr/bin/env python\n # SPDX-License-Identifier: BSD-3-Clause\n-# Copyright(c) 2010-2014 Intel Corporation\n+# Copyright(c) 2010-2018 Intel Corporation\n #\n \n+from DPDKConfigLib import DevInfo, DevUtil\n import sys\n-import os\n import getopt\n-import subprocess\n-from os.path import exists, abspath, dirname, basename\n-\n-# The PCI base class for all devices\n-network_class = {'Class': '02', 'Vendor': None, 'Device': None,\n- 'SVendor': None, 'SDevice': None}\n-encryption_class = {'Class': '10', 'Vendor': None, 'Device': None,\n- 'SVendor': None, 'SDevice': None}\n-intel_processor_class = {'Class': '0b', 'Vendor': '8086', 'Device': None,\n- 'SVendor': None, 'SDevice': None}\n-cavium_sso = {'Class': '08', 'Vendor': '177d', 'Device': 'a04b,a04d',\n- 'SVendor': None, 'SDevice': None}\n-cavium_fpa = {'Class': '08', 'Vendor': '177d', 'Device': 'a053',\n- 'SVendor': None, 'SDevice': None}\n-cavium_pkx = {'Class': '08', 'Vendor': '177d', 'Device': 'a0dd,a049',\n- 'SVendor': None, 'SDevice': None}\n-cavium_tim = {'Class': '08', 'Vendor': '177d', 'Device': 'a051',\n- 'SVendor': None, 'SDevice': None}\n-avp_vnic = {'Class': '05', 'Vendor': '1af4', 'Device': '1110',\n- 'SVendor': None, 'SDevice': None}\n-\n-network_devices = [network_class, cavium_pkx, avp_vnic]\n-crypto_devices = [encryption_class, intel_processor_class]\n-eventdev_devices = [cavium_sso, cavium_tim]\n-mempool_devices = [cavium_fpa]\n-\n-# global dict ethernet devices present. Dictionary indexed by PCI address.\n-# Each device within this is itself a dictionary of device properties\n-devices = {}\n-# list of supported DPDK drivers\n-dpdk_drivers = [\"igb_uio\", \"vfio-pci\", \"uio_pci_generic\"]\n+from os.path import basename\n \n # command-line arg flags\n b_flag = None\n status_flag = False\n force_flag = False\n+status_dev = \"\"\n args = []\n \n \n@@ -116,394 +87,43 @@ def usage():\n \"\"\" % locals()) # replace items from local variables\n \n \n-# This is roughly compatible with check_output function in subprocess module\n-# which is only available in python 2.7.\n-def check_output(args, stderr=None):\n- '''Run a command and capture its output'''\n- return subprocess.Popen(args, stdout=subprocess.PIPE,\n- stderr=stderr).communicate()[0]\n-\n-\n def check_modules():\n '''Checks that igb_uio is loaded'''\n- global dpdk_drivers\n+ loaded_drivers = DevUtil.get_loaded_dpdk_drivers()\n+ supported_drivers = DevUtil.get_supported_dpdk_drivers()\n \n- # list of supported modules\n- mods = [{\"Name\": driver, \"Found\": False} for driver in dpdk_drivers]\n-\n- # first check if module is loaded\n- try:\n- # Get list of sysfs modules (both built-in and dynamically loaded)\n- sysfs_path = '/sys/module/'\n-\n- # Get the list of directories in sysfs_path\n- sysfs_mods = [os.path.join(sysfs_path, o) for o\n- in os.listdir(sysfs_path)\n- if os.path.isdir(os.path.join(sysfs_path, o))]\n-\n- # Extract the last element of '/sys/module/abc' in the array\n- sysfs_mods = [a.split('/')[-1] for a in sysfs_mods]\n-\n- # special case for vfio_pci (module is named vfio-pci,\n- # but its .ko is named vfio_pci)\n- sysfs_mods = [a if a != 'vfio_pci' else 'vfio-pci' for a in sysfs_mods]\n-\n- for mod in mods:\n- if mod[\"Name\"] in sysfs_mods:\n- mod[\"Found\"] = True\n- except:\n- pass\n+ if b_flag in supported_drivers and b_flag not in loaded_drivers:\n+ print(\"Error - %s driver is not loaded\" % b_flag)\n+ sys.exit(1)\n \n # check if we have at least one loaded module\n- if True not in [mod[\"Found\"] for mod in mods] and b_flag is not None:\n- if b_flag in dpdk_drivers:\n- print(\"Error - no supported modules(DPDK driver) are loaded\")\n- sys.exit(1)\n- else:\n- print(\"Warning - no supported modules(DPDK driver) are loaded\")\n-\n- # change DPDK driver list to only contain drivers that are loaded\n- dpdk_drivers = [mod[\"Name\"] for mod in mods if mod[\"Found\"]]\n-\n-\n-def has_driver(dev_id):\n- '''return true if a device is assigned to a driver. False otherwise'''\n- return \"Driver_str\" in devices[dev_id]\n-\n-\n-def get_pci_device_details(dev_id, probe_lspci):\n- '''This function gets additional details for a PCI device'''\n- device = {}\n-\n- if probe_lspci:\n- extra_info = check_output([\"lspci\", \"-vmmks\", dev_id]).splitlines()\n-\n- # parse lspci details\n- for line in extra_info:\n- if len(line) == 0:\n- continue\n- name, value = line.decode().split(\"\\t\", 1)\n- name = name.strip(\":\") + \"_str\"\n- device[name] = value\n- # check for a unix interface name\n- device[\"Interface\"] = \"\"\n- for base, dirs, _ in os.walk(\"/sys/bus/pci/devices/%s/\" % dev_id):\n- if \"net\" in dirs:\n- device[\"Interface\"] = \\\n- \",\".join(os.listdir(os.path.join(base, \"net\")))\n- break\n- # check if a port is used for ssh connection\n- device[\"Ssh_if\"] = False\n- device[\"Active\"] = \"\"\n-\n- return device\n-\n-def clear_data():\n- '''This function clears any old data'''\n- devices = {}\n-\n-def get_device_details(devices_type):\n- '''This function populates the \"devices\" dictionary. The keys used are\n- the pci addresses (domain:bus:slot.func). The values are themselves\n- dictionaries - one for each NIC.'''\n- global devices\n- global dpdk_drivers\n-\n- # first loop through and read details for all devices\n- # request machine readable format, with numeric IDs and String\n- dev = {}\n- dev_lines = check_output([\"lspci\", \"-Dvmmnnk\"]).splitlines()\n- for dev_line in dev_lines:\n- if len(dev_line) == 0:\n- if device_type_match(dev, devices_type):\n- # Replace \"Driver\" with \"Driver_str\" to have consistency of\n- # of dictionary key names\n- if \"Driver\" in dev.keys():\n- dev[\"Driver_str\"] = dev.pop(\"Driver\")\n- if \"Module\" in dev.keys():\n- dev[\"Module_str\"] = dev.pop(\"Module\")\n- # use dict to make copy of dev\n- devices[dev[\"Slot\"]] = dict(dev)\n- # Clear previous device's data\n- dev = {}\n- else:\n- name, value = dev_line.decode().split(\"\\t\", 1)\n- value_list = value.rsplit(' ', 1)\n- if len(value_list) > 1:\n- # String stored in <name>_str\n- dev[name.rstrip(\":\") + '_str'] = value_list[0]\n- # Numeric IDs\n- dev[name.rstrip(\":\")] = value_list[len(value_list) - 1] \\\n- .rstrip(\"]\").lstrip(\"[\")\n-\n- if devices_type == network_devices:\n- # check what is the interface if any for an ssh connection if\n- # any to this host, so we can mark it later.\n- ssh_if = []\n- route = check_output([\"ip\", \"-o\", \"route\"])\n- # filter out all lines for 169.254 routes\n- route = \"\\n\".join(filter(lambda ln: not ln.startswith(\"169.254\"),\n- route.decode().splitlines()))\n- rt_info = route.split()\n- for i in range(len(rt_info) - 1):\n- if rt_info[i] == \"dev\":\n- ssh_if.append(rt_info[i+1])\n-\n- # based on the basic info, get extended text details\n- for d in devices.keys():\n- if not device_type_match(devices[d], devices_type):\n- continue\n-\n- # get additional info and add it to existing data\n- devices[d] = devices[d].copy()\n- # No need to probe lspci\n- devices[d].update(get_pci_device_details(d, False).items())\n-\n- if devices_type == network_devices:\n- for _if in ssh_if:\n- if _if in devices[d][\"Interface\"].split(\",\"):\n- devices[d][\"Ssh_if\"] = True\n- devices[d][\"Active\"] = \"*Active*\"\n- break\n-\n- # add igb_uio to list of supporting modules if needed\n- if \"Module_str\" in devices[d]:\n- for driver in dpdk_drivers:\n- if driver not in devices[d][\"Module_str\"]:\n- devices[d][\"Module_str\"] = \\\n- devices[d][\"Module_str\"] + \",%s\" % driver\n- else:\n- devices[d][\"Module_str\"] = \",\".join(dpdk_drivers)\n-\n- # make sure the driver and module strings do not have any duplicates\n- if has_driver(d):\n- modules = devices[d][\"Module_str\"].split(\",\")\n- if devices[d][\"Driver_str\"] in modules:\n- modules.remove(devices[d][\"Driver_str\"])\n- devices[d][\"Module_str\"] = \",\".join(modules)\n-\n-\n-def device_type_match(dev, devices_type):\n- for i in range(len(devices_type)):\n- param_count = len(\n- [x for x in devices_type[i].values() if x is not None])\n- match_count = 0\n- if dev[\"Class\"][0:2] == devices_type[i][\"Class\"]:\n- match_count = match_count + 1\n- for key in devices_type[i].keys():\n- if key != 'Class' and devices_type[i][key]:\n- value_list = devices_type[i][key].split(',')\n- for value in value_list:\n- if value.strip(' ') == dev[key]:\n- match_count = match_count + 1\n- # count must be the number of non None parameters to match\n- if match_count == param_count:\n- return True\n- return False\n-\n-def dev_id_from_dev_name(dev_name):\n- '''Take a device \"name\" - a string passed in by user to identify a NIC\n- device, and determine the device id - i.e. the domain:bus:slot.func - for\n- it, which can then be used to index into the devices array'''\n-\n- # check if it's already a suitable index\n- if dev_name in devices:\n- return dev_name\n- # check if it's an index just missing the domain part\n- elif \"0000:\" + dev_name in devices:\n- return \"0000:\" + dev_name\n- else:\n- # check if it's an interface name, e.g. eth1\n- for d in devices.keys():\n- if dev_name in devices[d][\"Interface\"].split(\",\"):\n- return devices[d][\"Slot\"]\n- # if nothing else matches - error\n- print(\"Unknown device: %s. \"\n- \"Please specify device in \\\"bus:slot.func\\\" format\" % dev_name)\n- sys.exit(1)\n-\n-\n-def unbind_one(dev_id, force):\n- '''Unbind the device identified by \"dev_id\" from its current driver'''\n- dev = devices[dev_id]\n- if not has_driver(dev_id):\n- print(\"%s %s %s is not currently managed by any driver\\n\" %\n- (dev[\"Slot\"], dev[\"Device_str\"], dev[\"Interface\"]))\n- return\n-\n- # prevent us disconnecting ourselves\n- if dev[\"Ssh_if\"] and not force:\n- print(\"Routing table indicates that interface %s is active. \"\n- \"Skipping unbind\" % (dev_id))\n- return\n-\n- # write to /sys to unbind\n- filename = \"/sys/bus/pci/drivers/%s/unbind\" % dev[\"Driver_str\"]\n- try:\n- f = open(filename, \"a\")\n- except:\n- print(\"Error: unbind failed for %s - Cannot open %s\"\n- % (dev_id, filename))\n- sys.exit(1)\n- f.write(dev_id)\n- f.close()\n-\n-\n-def bind_one(dev_id, driver, force):\n- '''Bind the device given by \"dev_id\" to the driver \"driver\". If the device\n- is already bound to a different driver, it will be unbound first'''\n- dev = devices[dev_id]\n- saved_driver = None # used to rollback any unbind in case of failure\n-\n- # prevent disconnection of our ssh session\n- if dev[\"Ssh_if\"] and not force:\n- print(\"Routing table indicates that interface %s is active. \"\n- \"Not modifying\" % (dev_id))\n- return\n-\n- # unbind any existing drivers we don't want\n- if has_driver(dev_id):\n- if dev[\"Driver_str\"] == driver:\n- print(\"%s already bound to driver %s, skipping\\n\"\n- % (dev_id, driver))\n- return\n- else:\n- saved_driver = dev[\"Driver_str\"]\n- unbind_one(dev_id, force)\n- dev[\"Driver_str\"] = \"\" # clear driver string\n-\n- # For kernels >= 3.15 driver_override can be used to specify the driver\n- # for a device rather than relying on the driver to provide a positive\n- # match of the device. The existing process of looking up\n- # the vendor and device ID, adding them to the driver new_id,\n- # will erroneously bind other devices too which has the additional burden\n- # of unbinding those devices\n- if driver in dpdk_drivers:\n- filename = \"/sys/bus/pci/devices/%s/driver_override\" % dev_id\n- if os.path.exists(filename):\n- try:\n- f = open(filename, \"w\")\n- except:\n- print(\"Error: bind failed for %s - Cannot open %s\"\n- % (dev_id, filename))\n- return\n- try:\n- f.write(\"%s\" % driver)\n- f.close()\n- except:\n- print(\"Error: bind failed for %s - Cannot write driver %s to \"\n- \"PCI ID \" % (dev_id, driver))\n- return\n- # For kernels < 3.15 use new_id to add PCI id's to the driver\n- else:\n- filename = \"/sys/bus/pci/drivers/%s/new_id\" % driver\n- try:\n- f = open(filename, \"w\")\n- except:\n- print(\"Error: bind failed for %s - Cannot open %s\"\n- % (dev_id, filename))\n- return\n- try:\n- # Convert Device and Vendor Id to int to write to new_id\n- f.write(\"%04x %04x\" % (int(dev[\"Vendor\"],16),\n- int(dev[\"Device\"], 16)))\n- f.close()\n- except:\n- print(\"Error: bind failed for %s - Cannot write new PCI ID to \"\n- \"driver %s\" % (dev_id, driver))\n- return\n-\n- # do the bind by writing to /sys\n- filename = \"/sys/bus/pci/drivers/%s/bind\" % driver\n- try:\n- f = open(filename, \"a\")\n- except:\n- print(\"Error: bind failed for %s - Cannot open %s\"\n- % (dev_id, filename))\n- if saved_driver is not None: # restore any previous driver\n- bind_one(dev_id, saved_driver, force)\n- return\n- try:\n- f.write(dev_id)\n- f.close()\n- except:\n- # for some reason, closing dev_id after adding a new PCI ID to new_id\n- # results in IOError. however, if the device was successfully bound,\n- # we don't care for any errors and can safely ignore IOError\n- tmp = get_pci_device_details(dev_id, True)\n- if \"Driver_str\" in tmp and tmp[\"Driver_str\"] == driver:\n- return\n- print(\"Error: bind failed for %s - Cannot bind to driver %s\"\n- % (dev_id, driver))\n- if saved_driver is not None: # restore any previous driver\n- bind_one(dev_id, saved_driver, force)\n- return\n-\n- # For kernels > 3.15 driver_override is used to bind a device to a driver.\n- # Before unbinding it, overwrite driver_override with empty string so that\n- # the device can be bound to any other driver\n- filename = \"/sys/bus/pci/devices/%s/driver_override\" % dev_id\n- if os.path.exists(filename):\n- try:\n- f = open(filename, \"w\")\n- except:\n- print(\"Error: unbind failed for %s - Cannot open %s\"\n- % (dev_id, filename))\n- sys.exit(1)\n- try:\n- f.write(\"\\00\")\n- f.close()\n- except:\n- print(\"Error: unbind failed for %s - Cannot open %s\"\n- % (dev_id, filename))\n- sys.exit(1)\n+ if len(loaded_drivers) == 0:\n+ print(\"Warning - no supported modules(DPDK driver) are loaded\")\n \n \n def unbind_all(dev_list, force=False):\n \"\"\"Unbind method, takes a list of device locations\"\"\"\n-\n- if dev_list[0] == \"dpdk\":\n- for d in devices.keys():\n- if \"Driver_str\" in devices[d]:\n- if devices[d][\"Driver_str\"] in dpdk_drivers:\n- unbind_one(devices[d][\"Slot\"], force)\n- return\n-\n- dev_list = map(dev_id_from_dev_name, dev_list)\n- for d in dev_list:\n- unbind_one(d, force)\n+ try:\n+ DevUtil.unbind(dev_list, force)\n+ except DevUtil.UnbindException as e:\n+ print(\"Unbind failed: %s\" % e)\n+ sys.exit(1)\n \n \n def bind_all(dev_list, driver, force=False):\n \"\"\"Bind method, takes a list of device locations\"\"\"\n- global devices\n \n- dev_list = map(dev_id_from_dev_name, dev_list)\n+ try:\n+ DevUtil.bind(dev_list, driver, force)\n+ except DevUtil.BindException as e:\n+ print(\"Bind failed: %s\" % e)\n+ sys.exit(1)\n+ except DevUtil.UnbindException as e:\n+ print(\"Bind failed: %s\" % e)\n+ sys.exit(1)\n \n- for d in dev_list:\n- bind_one(d, driver, force)\n \n- # For kernels < 3.15 when binding devices to a generic driver\n- # (i.e. one that doesn't have a PCI ID table) using new_id, some devices\n- # that are not bound to any other driver could be bound even if no one has\n- # asked them to. hence, we check the list of drivers again, and see if\n- # some of the previously-unbound devices were erroneously bound.\n- if not os.path.exists(\"/sys/bus/pci/devices/%s/driver_override\" % d):\n- for d in devices.keys():\n- # skip devices that were already bound or that we know should be bound\n- if \"Driver_str\" in devices[d] or d in dev_list:\n- continue\n-\n- # update information about this device\n- devices[d] = dict(devices[d].items() +\n- get_pci_device_details(d, True).items())\n-\n- # check if updated information indicates that the device was bound\n- if \"Driver_str\" in devices[d]:\n- unbind_one(d, force)\n-\n-\n-def display_devices(title, dev_list, extra_params=None):\n+def display_devices(title, dev_list):\n '''Displays to the user the details of a list of devices given in\n \"dev_list\". The \"extra_params\" parameter, if given, should contain a string\n with %()s fields in it for replacement by the named fields in each\n@@ -515,59 +135,73 @@ def display_devices(title, dev_list, extra_params=None):\n strings.append(\"<none>\")\n else:\n for dev in dev_list:\n- if extra_params is not None:\n- strings.append(\"%s '%s %s' %s\" % (dev[\"Slot\"],\n- dev[\"Device_str\"],\n- dev[\"Device\"],\n- extra_params % dev))\n+ if dev.devtype == DevInfo.DeviceType.DEVTYPE_NETWORK:\n+ extra_str = \"if=%s drv=%s unused=%s%s\" % \\\n+ (\",\".join(dev.interfaces), dev.active_driver,\n+ \",\".join(dev.available_drivers),\n+ \" *Active*\" if dev.active_interface else \"\")\n else:\n- strings.append(\"%s '%s'\" % (dev[\"Slot\"], dev[\"Device_str\"]))\n+ extra_str = \"drv=%s unused=%s\" % \\\n+ (dev.active_driver, \",\".join(dev.available_drivers))\n+ strings.append(\"%s '%s %s' %s\" % (dev.pci_addr,\n+ dev.device_name,\n+ dev.device_id,\n+ extra_str))\n # sort before printing, so that the entries appear in PCI order\n strings.sort()\n print(\"\\n\".join(strings)) # print one per line\n \n-def show_device_status(devices_type, device_name):\n- global dpdk_drivers\n+\n+def show_device_status(device_list, device_type):\n kernel_drv = []\n dpdk_drv = []\n no_drv = []\n \n+ typenames = {\n+ DevInfo.DeviceType.DEVTYPE_NETWORK: \"Network\",\n+ DevInfo.DeviceType.DEVTYPE_CRYPTO: \"Crypto\",\n+ DevInfo.DeviceType.DEVTYPE_EVENT: \"Event\",\n+ DevInfo.DeviceType.DEVTYPE_MEMPOOL: \"Mempool\"\n+ }\n+ typename = typenames[device_type]\n+\n # split our list of network devices into the three categories above\n- for d in devices.keys():\n- if device_type_match(devices[d], devices_type):\n- if not has_driver(d):\n- no_drv.append(devices[d])\n- continue\n- if devices[d][\"Driver_str\"] in dpdk_drivers:\n- dpdk_drv.append(devices[d])\n+ for d in device_list:\n+ if d.devtype == device_type:\n+ if d.active_driver == \"\":\n+ no_drv.append(d)\n+ elif d.active_driver in DevInfo.get_loaded_dpdk_drivers():\n+ dpdk_drv.append(d)\n else:\n- kernel_drv.append(devices[d])\n+ kernel_drv.append(d)\n \n # print each category separately, so we can clearly see what's used by DPDK\n- display_devices(\"%s devices using DPDK-compatible driver\" % device_name,\n- dpdk_drv, \"drv=%(Driver_str)s unused=%(Module_str)s\")\n- display_devices(\"%s devices using kernel driver\" % device_name, kernel_drv,\n- \"if=%(Interface)s drv=%(Driver_str)s \"\n- \"unused=%(Module_str)s %(Active)s\")\n- display_devices(\"Other %s devices\" % device_name, no_drv,\n- \"unused=%(Module_str)s\")\n+ display_devices(\"%s devices using DPDK-compatible driver\" % typename,\n+ dpdk_drv)\n+ display_devices(\"%s devices using kernel driver\" % typename, kernel_drv)\n+ display_devices(\"Other %s devices\" % typename, no_drv)\n+\n \n def show_status():\n '''Function called when the script is passed the \"--status\" option.\n Displays to the user what devices are bound to the igb_uio driver, the\n kernel driver or to no driver'''\n \n- if status_dev == \"net\" or status_dev == \"all\":\n- show_device_status(network_devices, \"Network\")\n+ devtypes = {\n+ \"net\": DevInfo.DeviceType.DEVTYPE_NETWORK,\n+ \"crypto\": DevInfo.DeviceType.DEVTYPE_CRYPTO,\n+ \"event\": DevInfo.DeviceType.DEVTYPE_EVENT,\n+ \"mempool\": DevInfo.DeviceType.DEVTYPE_MEMPOOL\n+ }\n+ device_list = DevInfo.get_devices().values()\n \n- if status_dev == \"crypto\" or status_dev == \"all\":\n- show_device_status(crypto_devices, \"Crypto\")\n+ found_types = sorted([devtypes[t] for t in devtypes.keys()\n+ if t == status_dev or status_dev == \"all\"])\n \n- if status_dev == \"event\" or status_dev == \"all\":\n- show_device_status(eventdev_devices, \"Eventdev\")\n+ for t in found_types:\n+ devices = list(filter(lambda dev: dev.devtype == t, device_list))\n+ show_device_status(devices, t)\n \n- if status_dev == \"mempool\" or status_dev == \"all\":\n- show_device_status(mempool_devices, \"Mempool\")\n \n def parse_args():\n '''Parses the command-line arguments given by the user and takes the\n@@ -635,13 +269,6 @@ def do_arg_actions():\n elif b_flag is not None:\n bind_all(args, b_flag, force_flag)\n if status_flag:\n- if b_flag is not None:\n- clear_data()\n- # refresh if we have changed anything\n- get_device_details(network_devices)\n- get_device_details(crypto_devices)\n- get_device_details(eventdev_devices)\n- get_device_details(mempool_devices)\n show_status()\n \n \n@@ -649,11 +276,6 @@ def main():\n '''program main function'''\n parse_args()\n check_modules()\n- clear_data()\n- get_device_details(network_devices)\n- get_device_details(crypto_devices)\n- get_device_details(eventdev_devices)\n- get_device_details(mempool_devices)\n do_arg_actions()\n \n if __name__ == \"__main__\":\n", "prefixes": [ "RFC", "6/9" ] }{ "id": 41486, "url": "