"Fossies" - the Fresh Open Source Software Archive

Member "openstack-cyborg-9.0.0/cyborg/accelerator/drivers/nic/intel/sysinfo.py" (5 Oct 2022, 8159 Bytes) of package /linux/misc/openstack/openstack-cyborg-9.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "sysinfo.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 8.0.0_vs_9.0.0.

    1 # Copyright 2020 Intel, Inc.
    2 #
    3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
    4 # not use this file except in compliance with the License. You may obtain
    5 # a copy of the License at
    6 #
    7 #      http://www.apache.org/licenses/LICENSE-2.0
    8 #
    9 # Unless required by applicable law or agreed to in writing, software
   10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   12 # License for the specific language governing permissions and limitations
   13 # under the License.
   14 
   15 
   16 """
   17 Cyborg Intel NIC driver implementation.
   18 """
   19 
   20 
   21 import glob
   22 import os
   23 import socket
   24 
   25 from oslo_config import cfg
   26 from oslo_log import log as logging
   27 from oslo_serialization import jsonutils
   28 
   29 from cyborg.accelerator.common import utils
   30 import cyborg.conf
   31 
   32 from cyborg.objects.driver_objects import driver_attach_handle
   33 from cyborg.objects.driver_objects import driver_attribute
   34 from cyborg.objects.driver_objects import driver_controlpath_id
   35 from cyborg.objects.driver_objects import driver_deployable
   36 from cyborg.objects.driver_objects import driver_device
   37 
   38 LOG = logging.getLogger(__name__)
   39 
   40 PCI_DEVICES_PATH_PATTERN = "/sys/bus/pci/devices/*"
   41 KNOWN_NICS = [("0x8086", "0x158b"), ("0x8086", "0x1572")]
   42 DRIVER_NAME = "intel"
   43 
   44 VF = "virtfn*"
   45 _SRIOV_TOTALVFS = "sriov_totalvfs"
   46 CONF = cyborg.conf.CONF
   47 
   48 
   49 def _parse_config():
   50     # parse nic config.
   51     cyborg.conf.devices.register_dynamic_opts(CONF)
   52     try:
   53         pdm = utils.parse_mappings(CONF.x710_static.physical_device_mappings)
   54         fdm = utils.parse_mappings(CONF.x710_static.function_device_mappings)
   55     except cfg.NoSuchOptError:
   56         return None, None
   57     else:
   58         return pdm, fdm
   59 
   60 
   61 def get_physical_network_and_traits(pci_info, physnet_device_mappings,
   62                                     function_device_mappings, pf_nic=None):
   63     traits = []
   64     physnet = None
   65     func_name = None
   66 
   67     if pf_nic:
   68         pf_addr = pf_nic["device"]
   69         traits.append("CUSTOM_VF")
   70     else:
   71         pf_addr = pci_info["PCI_SLOT_NAME"]
   72         traits.append("CUSTOM_PF")
   73     if not pf_addr:
   74         LOG.error("Incorrect report data received. Missing PF info.")
   75 
   76     pf_ifname = utils.get_ifname_by_pci_address(pf_addr)
   77 
   78     if physnet_device_mappings:
   79         for key, devices in physnet_device_mappings.items():
   80             if pf_ifname in devices:
   81                 physnet = key
   82                 break
   83     if function_device_mappings:
   84         for key, devices in function_device_mappings.items():
   85             if pf_ifname in devices:
   86                 func_name = key
   87                 break
   88     if func_name:
   89         traits.append("CUSTOM_" + func_name.upper())
   90     if physnet:
   91         traits.append("CUSTOM_" + physnet.upper())
   92 
   93     return {"traits": traits, "physical_network": physnet}
   94 
   95 
   96 def read_line(filename):
   97     with open(filename) as f:
   98         return f.readline().strip()
   99 
  100 
  101 def find_nics_by_know_list():
  102     return set(filter(
  103         lambda p: (
  104             read_line(os.path.join(p, "vendor")),
  105             read_line(os.path.join(p, "device"))
  106         ) in KNOWN_NICS,
  107         glob.glob(PCI_DEVICES_PATH_PATTERN)))
  108 
  109 
  110 def pci_attributes(path):
  111     with open(os.path.join(path, "uevent")) as f:
  112         attributes = dict(map(
  113             lambda p: p.strip().split("="),
  114             f.readlines()
  115         ))
  116 
  117     with open(os.path.join(path, "vendor")) as f:
  118         attributes["VENDOR"] = f.readline().strip()
  119 
  120     with open(os.path.join(path, "device")) as f:
  121         attributes["PRODUCT_ID"] = f.readline().strip()
  122 
  123     return attributes
  124 
  125 
  126 def nic_gen(path, physnet_device_mappings=None, function_device_mappings=None,
  127             pf_nic=None):
  128     pci_info = pci_attributes(path)
  129     nic = {
  130         "name": "_".join((socket.gethostname(), pci_info["PCI_SLOT_NAME"])),
  131         "device": pci_info["PCI_SLOT_NAME"],
  132         "type": "NIC",
  133         "vendor": pci_info["VENDOR"],
  134         "product_id": pci_info["PRODUCT_ID"],
  135         "rc": "CUSTOM_NIC",
  136         "stub": False,
  137         }
  138     # TODO(Xinran): need check device id and call get_traits differently.
  139     updates = get_physical_network_and_traits(pci_info,
  140                                               physnet_device_mappings,
  141                                               function_device_mappings,
  142                                               pf_nic)
  143 
  144     nic.update(updates)
  145     return nic
  146 
  147 
  148 def all_pfs_with_vf():
  149     return set(filter(
  150         lambda p: glob.glob(os.path.join(p, VF)),
  151         find_nics_by_know_list()))
  152 
  153 
  154 def all_vfs_in_pf(pf_path):
  155     return map(
  156         lambda p:
  157         os.path.join(
  158             os.path.dirname(os.path.dirname(p)),
  159             os.path.basename(os.readlink(p))),
  160         glob.glob(os.path.join(pf_path, VF)))
  161 
  162 
  163 def nic_tree():
  164     physnet_device_mappings, function_device_mappings = _parse_config()
  165     nics = []
  166     pfs_has_vf = all_pfs_with_vf()
  167     for n in find_nics_by_know_list():
  168         nic = nic_gen(n, physnet_device_mappings, function_device_mappings)
  169         if n in pfs_has_vf:
  170             vfs = []
  171             for vf in all_vfs_in_pf(n):
  172                 vf_nic = nic_gen(vf, physnet_device_mappings,
  173                                  function_device_mappings, nic)
  174                 vfs.append(vf_nic)
  175             nic["vfs"] = vfs
  176         nics.append(_generate_driver_device(nic))
  177     return nics
  178 
  179 
  180 def _generate_driver_device(nic):
  181     driver_device_obj = driver_device.DriverDevice()
  182     driver_device_obj.vendor = nic["vendor"]
  183     driver_device_obj.stub = nic["stub"]
  184     driver_device_obj.model = nic.get("model", "miss_model_info")
  185     driver_device_obj.vendor_board_info = nic.get(
  186         "vendor_board_info",
  187         "miss_vb_info")
  188     std_board_info = {"product_id": nic.get("product_id")}
  189     driver_device_obj.std_board_info = jsonutils.dumps(std_board_info)
  190     driver_device_obj.type = nic["type"]
  191     driver_device_obj.controlpath_id = _generate_controlpath_id(nic)
  192     driver_device_obj.deployable_list = _generate_dep_list(nic)
  193     return driver_device_obj
  194 
  195 
  196 def _generate_controlpath_id(nic):
  197     driver_cpid = driver_controlpath_id.DriverControlPathID()
  198     driver_cpid.cpid_type = "PCI"
  199     driver_cpid.cpid_info = utils.pci_str_to_json(nic["device"])
  200     return driver_cpid
  201 
  202 
  203 def _generate_dep_list(nic):
  204     dep_list = []
  205     # pf without sriov enabled.
  206     if "vfs" not in nic:
  207         driver_dep = driver_deployable.DriverDeployable()
  208         driver_dep.num_accelerators = 1
  209         driver_dep.attach_handle_list = [
  210             _generate_attach_handle(nic)]
  211         driver_dep.name = nic["name"]
  212         driver_dep.driver_name = DRIVER_NAME
  213         driver_dep.attribute_list = _generate_attribute_list(nic)
  214         dep_list = [driver_dep]
  215     # pf with sriov enabled, may have several vfs.
  216     else:
  217         for vf in nic["vfs"]:
  218             driver_dep = driver_deployable.DriverDeployable()
  219             driver_dep.num_accelerators = 1
  220             driver_dep.attach_handle_list = [
  221                 _generate_attach_handle(vf)]
  222             driver_dep.name = vf["name"]
  223             driver_dep.driver_name = DRIVER_NAME
  224             driver_dep.attribute_list = _generate_attribute_list(vf)
  225             dep_list.append(driver_dep)
  226     return dep_list
  227 
  228 
  229 def _generate_attach_handle(nic):
  230     driver_ah = driver_attach_handle.DriverAttachHandle()
  231     driver_ah.attach_type = "PCI"
  232     driver_ah.attach_info = utils.pci_str_to_json(nic["device"],
  233                                                   nic["physical_network"])
  234     driver_ah.in_use = False
  235     return driver_ah
  236 
  237 
  238 def _generate_attribute_list(nic):
  239     attr_list = []
  240     for k, v in nic.items():
  241         if k == "rc":
  242             driver_attr = driver_attribute.DriverAttribute()
  243             driver_attr.key, driver_attr.value = k, v
  244             attr_list.append(driver_attr)
  245         if k == "traits":
  246             values = nic.get(k, [])
  247             for index, val in enumerate(values):
  248                 driver_attr = driver_attribute.DriverAttribute()
  249                 driver_attr.key = "trait" + str(index)
  250                 driver_attr.value = val
  251                 attr_list.append(driver_attr)
  252 
  253     return attr_list