Add a new driver for Intel QAT card
Please see the test report in https://wiki.openstack.org/wiki/Cyborg/TestReport/IntelQAT. This patch implemented Intel QAT driver in Cyborg. The spec is already merged. Please see: https://specs.openstack.org/openstack/cyborg-specs/specs/victoria/approved/qat-driver-proposal.html Story: 2008025 Task: 40679 Change-Id: Ibef3a5327a838b4867ed8d93951f6138c9f76a7d Co-Authored-By: Jintao Wang(jintao.wang@intel.com)
This commit is contained in:
parent
9179ed3053
commit
d560ec1fc3
|
@ -0,0 +1,46 @@
|
|||
# Copyright 2018 Intel, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
"""
|
||||
Cyborg QAT driver implementation.
|
||||
"""
|
||||
|
||||
VENDOR_MAPS = {"0x8086": "intel"}
|
||||
|
||||
|
||||
class QATDriver(object):
|
||||
"""Base class for QAT drivers.
|
||||
|
||||
This is just a virtual QAT drivers interface.
|
||||
Vendor should implement their specific drivers.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def create(cls, vendor, *args, **kwargs):
|
||||
for sclass in cls.__subclasses__():
|
||||
vendor = VENDOR_MAPS.get(vendor, vendor)
|
||||
if vendor == sclass.VENDOR:
|
||||
return sclass(*args, **kwargs)
|
||||
raise LookupError("Not find the QAT driver for vendor %s" % vendor)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def discover(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
@classmethod
|
||||
def discover_vendors(cls):
|
||||
raise NotImplementedError()
|
|
@ -0,0 +1,36 @@
|
|||
# Copyright 2018 Intel, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
"""
|
||||
Cyborg Intel QAT driver implementation.
|
||||
"""
|
||||
|
||||
from cyborg.accelerator.drivers.qat.base import QATDriver
|
||||
from cyborg.accelerator.drivers.qat.intel import sysinfo
|
||||
|
||||
|
||||
class IntelQATDriver(QATDriver):
|
||||
"""Base class for QAT drivers.
|
||||
|
||||
This is just a virtual QAT drivers interface.
|
||||
Vendor should implement their specific drivers.
|
||||
"""
|
||||
VENDOR = "intel"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def discover(self):
|
||||
return sysinfo.qat_tree()
|
|
@ -0,0 +1,204 @@
|
|||
# Copyright 2020 Intel, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
"""
|
||||
Cyborg Intel QAT driver implementation.
|
||||
"""
|
||||
|
||||
|
||||
import glob
|
||||
import os
|
||||
import socket
|
||||
|
||||
from cyborg.accelerator.common import utils
|
||||
from cyborg.common import constants
|
||||
from cyborg.objects.driver_objects import driver_attach_handle
|
||||
from cyborg.objects.driver_objects import driver_attribute
|
||||
from cyborg.objects.driver_objects import driver_controlpath_id
|
||||
from cyborg.objects.driver_objects import driver_deployable
|
||||
from cyborg.objects.driver_objects import driver_device
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
|
||||
PCI_DEVICES_PATH = "/sys/bus/pci/devices"
|
||||
KNOW_QATS = [("0x8086", "0x37c8")]
|
||||
PF = "physfn"
|
||||
VF = "virtfn*"
|
||||
INTEL_QAT_DEV_PREFIX = "intel-qat-dev"
|
||||
RC_QAT = constants.RESOURCES["QAT"]
|
||||
DRIVER_NAME = "intel"
|
||||
|
||||
RESOURCES = {
|
||||
"qat": RC_QAT
|
||||
}
|
||||
|
||||
|
||||
def pci_attributes(path):
|
||||
with open(os.path.join(path, "uevent")) as f:
|
||||
attributes = dict(map(
|
||||
lambda p: p.strip().split("="),
|
||||
f.readlines()
|
||||
))
|
||||
|
||||
with open(os.path.join(path, "vendor")) as f:
|
||||
attributes["VENDOR"] = f.readline().strip()
|
||||
|
||||
with open(os.path.join(path, "device")) as f:
|
||||
attributes["PRODUCT_ID"] = f.readline().strip()
|
||||
|
||||
return attributes
|
||||
|
||||
|
||||
def get_link_targets(links):
|
||||
return map(
|
||||
lambda p:
|
||||
os.path.realpath(
|
||||
os.path.join(os.path.dirname(p), os.readlink(p))),
|
||||
links)
|
||||
|
||||
|
||||
def all_qats():
|
||||
return set(filter(
|
||||
lambda p: (
|
||||
pci_attributes(p)["VENDOR"],
|
||||
pci_attributes(p)["PRODUCT_ID"]
|
||||
) in KNOW_QATS,
|
||||
glob.glob(os.path.join(PCI_DEVICES_PATH, "*"))))
|
||||
|
||||
|
||||
def all_pfs_with_vf():
|
||||
return set(filter(
|
||||
lambda p: glob.glob(os.path.join(p, VF)),
|
||||
all_qats()))
|
||||
|
||||
|
||||
def all_vfs_in_pf(pf_path):
|
||||
return map(
|
||||
lambda p:
|
||||
os.path.join(
|
||||
os.path.dirname(os.path.dirname(p)),
|
||||
os.path.basename(os.readlink(p))),
|
||||
glob.glob(os.path.join(pf_path, VF)))
|
||||
|
||||
|
||||
def find_pf_by_vf(vf_path):
|
||||
return os.path.join(
|
||||
os.path.dirname(vf_path),
|
||||
os.path.basename(os.readlink(
|
||||
os.path.join(vf_path, PF))))
|
||||
|
||||
|
||||
def all_vfs():
|
||||
return map(
|
||||
lambda p: all_vfs_in_pf(p), all_pfs_with_vf()
|
||||
)
|
||||
|
||||
|
||||
def qat_gen(path):
|
||||
pci_info = pci_attributes(path)
|
||||
qat = {
|
||||
"name": "_".join((socket.gethostname(), pci_info["PCI_SLOT_NAME"])),
|
||||
"device": pci_info["PCI_SLOT_NAME"],
|
||||
"type": constants.DEVICE_QAT,
|
||||
"vendor": pci_info["VENDOR"],
|
||||
"product_id": pci_info["PRODUCT_ID"],
|
||||
"rc": RESOURCES["qat"],
|
||||
"stub": False,
|
||||
}
|
||||
return qat
|
||||
|
||||
|
||||
def qat_tree():
|
||||
devs = []
|
||||
pfs_has_vf = all_pfs_with_vf()
|
||||
for q in all_qats():
|
||||
qat = qat_gen(q)
|
||||
if q in pfs_has_vf:
|
||||
vfs = []
|
||||
for vf in all_vfs_in_pf(q):
|
||||
vf_qat = qat_gen(vf)
|
||||
vfs.append(vf_qat)
|
||||
qat["vfs"] = vfs
|
||||
devs.append(_generate_driver_device(qat))
|
||||
return devs
|
||||
|
||||
|
||||
def _generate_driver_device(qat):
|
||||
driver_device_obj = driver_device.DriverDevice()
|
||||
driver_device_obj.vendor = qat["vendor"]
|
||||
driver_device_obj.stub = qat["stub"]
|
||||
driver_device_obj.model = qat.get("model", "miss_model_info")
|
||||
driver_device_obj.vendor_board_info = qat.get(
|
||||
"vendor_board_info",
|
||||
"miss_vb_info")
|
||||
std_board_info = {"product_id": qat.get("product_id", None)}
|
||||
driver_device_obj.std_board_info = jsonutils.dumps(std_board_info)
|
||||
driver_device_obj.type = qat["type"]
|
||||
driver_device_obj.controlpath_id = _generate_controlpath_id(qat)
|
||||
driver_device_obj.deployable_list = _generate_dep_list(qat)
|
||||
return driver_device_obj
|
||||
|
||||
|
||||
def _generate_controlpath_id(qat):
|
||||
driver_cpid = driver_controlpath_id.DriverControlPathID()
|
||||
driver_cpid.cpid_type = "PCI"
|
||||
driver_cpid.cpid_info = utils.pci_str_to_json(qat["device"])
|
||||
return driver_cpid
|
||||
|
||||
|
||||
def _generate_dep_list(qat):
|
||||
dep_list = []
|
||||
# pf without sriov enabled.
|
||||
if "vfs" not in qat:
|
||||
driver_dep = driver_deployable.DriverDeployable()
|
||||
driver_dep.num_accelerators = 1
|
||||
driver_dep.attach_handle_list = [
|
||||
_generate_attach_handle(qat)]
|
||||
driver_dep.name = qat["name"]
|
||||
driver_dep.driver_name = DRIVER_NAME
|
||||
driver_dep.attribute_list = _generate_attribute_list(qat)
|
||||
dep_list = [driver_dep]
|
||||
# pf with sriov enabled, may have several vfs.
|
||||
else:
|
||||
for vf in qat["vfs"]:
|
||||
driver_dep = driver_deployable.DriverDeployable()
|
||||
driver_dep.num_accelerators = 1
|
||||
driver_dep.attach_handle_list = [
|
||||
_generate_attach_handle(vf)]
|
||||
driver_dep.name = vf["name"]
|
||||
driver_dep.driver_name = DRIVER_NAME
|
||||
driver_dep.attribute_list = _generate_attribute_list(qat)
|
||||
dep_list.append(driver_dep)
|
||||
return dep_list
|
||||
|
||||
|
||||
def _generate_attach_handle(qat):
|
||||
driver_ah = driver_attach_handle.DriverAttachHandle()
|
||||
driver_ah.attach_type = "PCI"
|
||||
driver_ah.attach_info = utils.pci_str_to_json(qat["device"])
|
||||
driver_ah.in_use = False
|
||||
return driver_ah
|
||||
|
||||
|
||||
def _generate_attribute_list(qat):
|
||||
attr_list = []
|
||||
for k, _ in qat.items():
|
||||
if k == "rc":
|
||||
driver_attr = driver_attribute.DriverAttribute()
|
||||
driver_attr.key = k
|
||||
driver_attr.value = qat.get(k, None)
|
||||
attr_list.append(driver_attr)
|
||||
return attr_list
|
|
@ -19,6 +19,7 @@ AGENT_TOPIC = 'cyborg-agent'
|
|||
DEVICE_GPU = 'GPU'
|
||||
DEVICE_FPGA = 'FPGA'
|
||||
DEVICE_AICHIP = 'AICHIP'
|
||||
DEVICE_QAT = 'QAT'
|
||||
|
||||
|
||||
ARQ_STATES = (ARQ_INITIAL, ARQ_BIND_STARTED, ARQ_BOUND, ARQ_UNBOUND,
|
||||
|
@ -57,7 +58,7 @@ ARQ_STATES_TRANSFORM_MATRIX = {
|
|||
|
||||
|
||||
# Device type
|
||||
DEVICE_TYPE = (DEVICE_GPU, DEVICE_FPGA, DEVICE_AICHIP)
|
||||
DEVICE_TYPE = (DEVICE_GPU, DEVICE_FPGA, DEVICE_AICHIP, DEVICE_QAT)
|
||||
|
||||
|
||||
# Attach handle type
|
||||
|
@ -74,7 +75,8 @@ CPID_TYPE = (CPID_TYPE_PCI) = ("PCI")
|
|||
RESOURCES = {
|
||||
"FPGA": orc.FPGA,
|
||||
"PGPU": orc.PGPU,
|
||||
"VGPU": orc.VGPU
|
||||
"VGPU": orc.VGPU,
|
||||
"QAT": "CUSTOM_QAT"
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,8 +90,8 @@ ACCEL_SPECS = (
|
|||
|
||||
|
||||
SUPPORT_RESOURCES = (
|
||||
FPGA, GPU, VGPU, PGPU) = (
|
||||
"FPGA", "GPU", "VGPU", "PGPU"
|
||||
FPGA, GPU, VGPU, PGPU, QAT) = (
|
||||
"FPGA", "GPU", "VGPU", "PGPU", "CUSTOM_QAT"
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
"""add_qat_type
|
||||
|
||||
Revision ID: 7e6f1f107f2b
|
||||
Revises: c1b5abada09c
|
||||
Create Date: 2019-07-17 04:21:52.055863
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '7e6f1f107f2b'
|
||||
down_revision = '60d8ac91fd20'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
new_device_type = sa.Enum('GPU', 'FPGA', 'AICHIP', 'QAT',
|
||||
name='device_type')
|
||||
op.alter_column('devices', 'type',
|
||||
existing_type=new_device_type,
|
||||
nullable=False)
|
|
@ -81,7 +81,7 @@ class Device(Base):
|
|||
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36), nullable=False, unique=True)
|
||||
type = Column(Enum('GPU', 'FPGA', 'AICHIP',
|
||||
type = Column(Enum('GPU', 'FPGA', 'AICHIP', 'QAT',
|
||||
name='device_type'), nullable=False)
|
||||
vendor = Column(String(255), nullable=False)
|
||||
model = Column(String(255), nullable=False)
|
||||
|
|
|
@ -0,0 +1,265 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright 2018 Intel, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import argparse
|
||||
import copy
|
||||
import os
|
||||
import shutil
|
||||
|
||||
|
||||
PF0_ADDR = "0000:05:00.0"
|
||||
PF1_ADDR = "0000:06:00.0"
|
||||
VF0_ADDR = "0000:05:01.0"
|
||||
QAT_TREE = {
|
||||
"dev.0": {"bdf": PF0_ADDR,
|
||||
"vfs": {"dev.2": {"bdf": VF0_ADDR}}},
|
||||
"dev.1": {"bdf": PF1_ADDR}}
|
||||
|
||||
SYS_DEVICES = "sys/devices"
|
||||
PCI_DEVICES_PATH = "sys/bus/pci/devices"
|
||||
|
||||
DEV_PREFIX = "intel-qat"
|
||||
|
||||
QAT_DEVICE_COMMON_SUB_DIR = ["power", "msi_irqs"]
|
||||
|
||||
QAT_DEVICE_COMMON_CONTENT = {
|
||||
"broken_parity_status": "0",
|
||||
"class": "0x0b4000",
|
||||
"config": "",
|
||||
"consistent_dma_mask_bits": "64",
|
||||
"d3cold_allowed": "1",
|
||||
"device": "0x37c8",
|
||||
"dma_mask_bits": "64",
|
||||
"driver_override": "(null)",
|
||||
"enable": "1",
|
||||
"irq": "33",
|
||||
"local_cpulist": "0-7,16-23",
|
||||
"local_cpus": "000000,00000000,00000000,00000000,00ff00ff",
|
||||
"max_link_speed": "5 GT/s",
|
||||
"max_link_width": "16",
|
||||
"modalias": "pci:v00008086d000037C8sv00008086sd00000002bc0Bsc40i00",
|
||||
"msi_bus": "1",
|
||||
"numa_node": "0",
|
||||
"resource0": "",
|
||||
"subsystem_device": "0x0002",
|
||||
"subsystem_vendor": "0x8086",
|
||||
"vendor": "0x8086"}
|
||||
|
||||
QAT_DEVICES_SPECIAL_COMMON_CONTENT = {
|
||||
"dev.0": {
|
||||
"resource": [
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x00000000d1340000 0x00000000d137ffff 0x0000000000140204",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x00000000d1300000 0x00000000d133ffff 0x0000000000140204",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x00000000d1390000 0x00000000d139ffff 0x0000000000140204",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x00000000d1390000 0x00000000d139ffff 0x0000000000140204",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000"],
|
||||
"resource2": "",
|
||||
"resource4": "",
|
||||
"sriov_numvfs": "1",
|
||||
"sriov_totalvfs": "1",
|
||||
"uevent": [
|
||||
"DRIVER=c6xx",
|
||||
"PCI_CLASS=B4000",
|
||||
"PCI_ID=8086:37C8",
|
||||
"PCI_SUBSYS_ID=8086:0002",
|
||||
"PCI_SLOT_NAME=0000:05:00.0",
|
||||
"MODALIAS=pci:v00008086d000037C8sv00008086sd00000002bc0Bsc40i00"],
|
||||
},
|
||||
"dev.1": {
|
||||
"resource": [
|
||||
"0x00000000fbc00000 0x00000000fbc7ffff 0x000000000014220c",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x00000000fbc80000 0x00000000fbcfffff 0x000000000014220c",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x00000000fbd00000 0x00000000fbd7ffff 0x000000000014220c",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000"],
|
||||
"resource2": "",
|
||||
"sriov_numvfs": "0",
|
||||
"sriov_totalvfs": "0",
|
||||
"uevent": [
|
||||
"DRIVER=c6xx",
|
||||
"PCI_CLASS=B4000",
|
||||
"PCI_ID=8086:37C8",
|
||||
"PCI_SUBSYS_ID=8086:0002",
|
||||
"PCI_SLOT_NAME=0000:06:00.0",
|
||||
"MODALIAS=pci:v00008086d000037C8sv00008086sd00000002bc0Bsc40i00"],
|
||||
},
|
||||
"dev.2": {
|
||||
"d3cold_allowed": "0",
|
||||
"device": "0x37c9",
|
||||
"modalias": "pci:v00008086d000037C9sv00008086sd00000000bc0Bsc40i00",
|
||||
"irq": "0",
|
||||
"resource": [
|
||||
"0x00000000c6100000 0x00000000c617ffff 0x000000000014220c",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000",
|
||||
"0x0000000000000000 0x0000000000000000 0x0000000000000000"],
|
||||
"uevent": [
|
||||
"DRIVER=c6xx",
|
||||
"PCI_CLASS=B4000",
|
||||
"PCI_ID=8086:37C8",
|
||||
"PCI_SUBSYS_ID=8086:0002",
|
||||
"PCI_SLOT_NAME=0000:05:01.0",
|
||||
"MODALIAS=pci:v00008086d000037C8sv00008086sd00000002bc0Bsc40i00"],
|
||||
}
|
||||
}
|
||||
|
||||
QAT_DEVICE_COMMON_SOFT_LINK = {
|
||||
"driver": "../../../../../../bus/pci/drivers/c6xx",
|
||||
"iommu": "../../../../../virtual/iommu/dmar1",
|
||||
"subsystem": "../../../../../../bus/pci"
|
||||
}
|
||||
|
||||
QAT_DEVICES_SPECIAL_SOFT_LINK = {
|
||||
"dev.0": {
|
||||
"driver": "../../../../../..//bus/pci/drivers/c6xx",
|
||||
"iommu_group": "../../../../../../kernel/iommu_groups/20",
|
||||
# "virtfn0": "../0000:05:01.0/",
|
||||
},
|
||||
"dev.1": {
|
||||
"driver": "../../../../../..//bus/pci/drivers/c6xx",
|
||||
"iommu_group": "../../../../../../kernel/iommu_groups/21",
|
||||
},
|
||||
"dev.2": {
|
||||
"iommu_group": "../../../../../../kernel/iommu_groups/67",
|
||||
# "physfn": "../0000:05:00.0/",
|
||||
}
|
||||
}
|
||||
|
||||
QAT_DEVICE_PF_SOFT_LINK = {
|
||||
"virtfn": lambda k, v: (k + str(int(v.rsplit(".", 1)[-1])),
|
||||
"/".join(["..", v]))
|
||||
}
|
||||
|
||||
QAT_DEVICE_VF_SOFT_LINK = {
|
||||
"physfn": lambda k, v: (k, "/".join(["..", v]))
|
||||
}
|
||||
|
||||
|
||||
def gen_qat_content(path, dev):
|
||||
content = copy.copy(QAT_DEVICE_COMMON_CONTENT)
|
||||
content.update(QAT_DEVICES_SPECIAL_COMMON_CONTENT[dev])
|
||||
for k, v in content.items():
|
||||
p = os.path.join(path, k)
|
||||
if not v:
|
||||
os.mknod(p)
|
||||
elif type(v) is str:
|
||||
with open(p, 'a') as f:
|
||||
f.write(v + "\n")
|
||||
elif type(v) is list:
|
||||
with open(p, 'a') as f:
|
||||
f.writelines([l + "\n" for l in v])
|
||||
|
||||
|
||||
def gen_qat_sub_dir(path):
|
||||
for d in QAT_DEVICE_COMMON_SUB_DIR:
|
||||
p = os.path.join(path, d)
|
||||
os.makedirs(p)
|
||||
|
||||
|
||||
def gen_qat_pf_soft_link(path, bdf):
|
||||
for k, v in QAT_DEVICE_PF_SOFT_LINK.items():
|
||||
if callable(v):
|
||||
k, v = v(k, bdf)
|
||||
os.symlink(v, os.path.join(path, k))
|
||||
|
||||
|
||||
def gen_qat_common_soft_link(path, bdf):
|
||||
for k, v in QAT_DEVICE_COMMON_SOFT_LINK.items():
|
||||
os.symlink(v, os.path.join(path, k))
|
||||
|
||||
|
||||
def gen_qat_vf_soft_link(path, bdf):
|
||||
for k, v in QAT_DEVICE_VF_SOFT_LINK.items():
|
||||
if callable(v):
|
||||
k, v = v(k, bdf)
|
||||
os.symlink(v, os.path.join(path, k))
|
||||
|
||||
|
||||
def create_devices_path_and_files(tree, device_path, vf=False, pfinfo=None):
|
||||
for k, v in tree.items():
|
||||
bdf = v["bdf"]
|
||||
pci_path = "pci" + bdf.rsplit(":", 1)[0]
|
||||
bdf_path = os.path.join(device_path, pci_path, bdf)
|
||||
ln = "-".join([DEV_PREFIX, k])
|
||||
dev_path = os.path.join(bdf_path, "qat", ln)
|
||||
os.makedirs(dev_path)
|
||||
gen_qat_content(bdf_path, k)
|
||||
gen_qat_sub_dir(bdf_path)
|
||||
if vf:
|
||||
gen_qat_pf_soft_link(pfinfo["path"], bdf)
|
||||
gen_qat_vf_soft_link(bdf_path, pfinfo["bdf"])
|
||||
pfinfo = {"path": bdf_path, "bdf": bdf}
|
||||
if "vfs" in v:
|
||||
create_devices_path_and_files(
|
||||
v["vfs"], device_path, True, pfinfo)
|
||||
os.symlink("../../../" + bdf, os.path.join(dev_path, "device"))
|
||||
pci_dev = os.path.join(device_path.split(SYS_DEVICES)[0],
|
||||
PCI_DEVICES_PATH)
|
||||
if not os.path.exists(pci_dev):
|
||||
os.makedirs(pci_dev)
|
||||
os.symlink("../../.." + bdf_path.split("sys")[-1],
|
||||
os.path.join(pci_dev, bdf))
|
||||
|
||||
|
||||
def create_fake_sysfs(prefix=""):
|
||||
sys_device = os.path.join(prefix, SYS_DEVICES)
|
||||
basedir = os.path.dirname(sys_device)
|
||||
if os.path.exists(basedir):
|
||||
shutil.rmtree(basedir, ignore_errors=False, onerror=None)
|
||||
create_devices_path_and_files(QAT_TREE, sys_device)
|
||||
|
||||
|
||||
def main():
|
||||
create_fake_sysfs()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate a fake sysfs for intel QAT.")
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument("-v", "--verbose", action="store_true")
|
||||
group.add_argument("-q", "--quiet", action="store_true")
|
||||
parser.add_argument("-p", "--prefix", type=str,
|
||||
default="/tmp", dest="p",
|
||||
help='Set the prefix path of the fake sysfs. '
|
||||
'default "/tmp"')
|
||||
args = parser.parse_args()
|
||||
|
||||
create_fake_sysfs(args.p)
|
|
@ -0,0 +1,109 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
from cyborg.accelerator.drivers.qat.intel import sysinfo
|
||||
|
||||
from cyborg.accelerator.drivers.qat.intel.driver import IntelQATDriver
|
||||
from cyborg.tests import base
|
||||
from cyborg.tests.unit.accelerator.drivers.qat.intel import prepare_test_data
|
||||
|
||||
import fixtures
|
||||
|
||||
|
||||
class TestIntelQATDriver(base.TestCase):
|
||||
def setUp(self):
|
||||
super(TestIntelQATDriver, self).setUp()
|
||||
self.pcipath = sysinfo.PCI_DEVICES_PATH
|
||||
tmp_sys_dir = self.useFixture(fixtures.TempDir())
|
||||
prepare_test_data.create_fake_sysfs(tmp_sys_dir.path)
|
||||
tmp_path = tmp_sys_dir.path
|
||||
sysinfo.PCI_DEVICES_PATH = os.path.join(
|
||||
tmp_path, sysinfo.PCI_DEVICES_PATH.split("/", 1)[-1])
|
||||
|
||||
def tearDown(self):
|
||||
super(TestIntelQATDriver, self).tearDown()
|
||||
sysinfo.PCI_DEVICES_PATH = self.pcipath
|
||||
|
||||
def test_discover(self):
|
||||
attach_handle_list = [
|
||||
[
|
||||
{'attach_type': 'PCI',
|
||||
'attach_info': '{"bus": "05", '
|
||||
'"device": "01", '
|
||||
'"domain": "0000", '
|
||||
'"function": "0"}',
|
||||
'in_use': False}
|
||||
],
|
||||
[
|
||||
{'attach_type': 'PCI',
|
||||
'attach_info': '{"bus": "06", '
|
||||
'"device": "00", '
|
||||
'"domain": "0000", '
|
||||
'"function": "0"}',
|
||||
'in_use': False}
|
||||
]
|
||||
]
|
||||
expected = [{'vendor': '0x8086',
|
||||
'type': 'QAT',
|
||||
'deployable_list':
|
||||
[
|
||||
{'num_accelerators': 1,
|
||||
'name': '0000:05:01.0',
|
||||
'attach_handle_list': attach_handle_list[0]
|
||||
},
|
||||
],
|
||||
'controlpath_id':
|
||||
{
|
||||
'cpid_info': '{"bus": "05", '
|
||||
'"device": "00", '
|
||||
'"domain": "0000", '
|
||||
'"function": "0"}',
|
||||
'cpid_type': 'PCI'}
|
||||
},
|
||||
{'vendor': '0x8086',
|
||||
'type': 'QAT',
|
||||
'deployable_list':
|
||||
[
|
||||
{'num_accelerators': 1,
|
||||
'name': '0000:06:00.0',
|
||||
'attach_handle_list': attach_handle_list[1]
|
||||
},
|
||||
],
|
||||
'controlpath_id':
|
||||
{
|
||||
'cpid_info': '{"bus": "06", '
|
||||
'"device": "00", '
|
||||
'"domain": "0000", '
|
||||
'"function": "0"}',
|
||||
'cpid_type': 'PCI'}
|
||||
}
|
||||
]
|
||||
intel = IntelQATDriver()
|
||||
qats = intel.discover()
|
||||
list.sort(qats, key=lambda x: x._obj_deployable_list[0].name)
|
||||
self.assertEqual(2, len(qats))
|
||||
for i in range(len(qats)):
|
||||
qat_dict = qats[i].as_dict()
|
||||
qat_dep_list = qat_dict['deployable_list']
|
||||
qat_attach_handle_list = \
|
||||
qat_dep_list[0].as_dict()['attach_handle_list']
|
||||
self.assertEqual(expected[i]['vendor'], qat_dict['vendor'])
|
||||
self.assertEqual(expected[i]['controlpath_id'],
|
||||
qat_dict['controlpath_id'])
|
||||
self.assertEqual(expected[i]['deployable_list'][0]
|
||||
['num_accelerators'],
|
||||
qat_dep_list[0].as_dict()['num_accelerators'])
|
||||
self.assertEqual(1, len(qat_attach_handle_list))
|
||||
self.assertEqual(attach_handle_list[i][0],
|
||||
qat_attach_handle_list[0].as_dict())
|
|
@ -0,0 +1,29 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from cyborg.accelerator.drivers.qat.base import QATDriver
|
||||
from cyborg.tests import base
|
||||
|
||||
|
||||
class TestQATDriver(base.TestCase):
|
||||
def test_create(self):
|
||||
QATDriver.create("intel")
|
||||
self.assertRaises(LookupError, QATDriver.create, "other")
|
||||
|
||||
def test_discover(self):
|
||||
d = QATDriver()
|
||||
self.assertRaises(NotImplementedError, d.discover)
|
||||
|
||||
def test_discover_vendors(self):
|
||||
d = QATDriver()
|
||||
self.assertRaises(NotImplementedError, d.discover_vendors)
|
|
@ -51,6 +51,7 @@ cyborg.accelerator.driver =
|
|||
nvidia_gpu_driver = cyborg.accelerator.drivers.gpu.nvidia.driver:NVIDIAGPUDriver
|
||||
fake_driver = cyborg.accelerator.drivers.fake:FakeDriver
|
||||
huawei_ascend_driver = cyborg.accelerator.drivers.aichip.huawei.ascend:AscendDriver
|
||||
intel_qat_driver = cyborg.accelerator.drivers.qat.intel.driver:IntelQATDriver
|
||||
|
||||
oslo.config.opts =
|
||||
cyborg = cyborg.conf.opts:list_opts
|
||||
|
|
Loading…
Reference in New Issue