2 # SPDX-License-Identifier: BSD-3-Clause
3 # Copyright(c) 2020 Intel Corporation
6 Configure an entire Intel DSA instance, using idxd kernel driver, for DPDK use
16 "Used to read/write paths in a sysfs directory"
17 def __init__(self, path):
20 def read_int(self, filename):
21 "Return a value from sysfs file"
22 with open(os.path.join(self.path, filename)) as f:
23 return int(f.readline())
25 def write_values(self, values):
26 "write dictionary, where key is filename and value is value to write"
27 for filename, contents in values.items():
28 with open(os.path.join(self.path, filename), "w") as f:
29 f.write(str(contents))
32 def get_drv_dir(dtype):
33 "Get the sysfs path for the driver, either 'idxd' or 'user'"
34 drv_dir = "/sys/bus/dsa/drivers/" + dtype
35 if not os.path.exists(drv_dir):
36 return "/sys/bus/dsa/drivers/dsa"
40 def reset_device(dsa_id):
41 "Reset the DSA device and all its queues"
42 drv_dir = SysfsDir(get_drv_dir("idxd"))
43 drv_dir.write_values({"unbind": f"dsa{dsa_id}"})
47 "Search for the sysfs directory of the PCI device"
48 base_dir = '/sys/bus/pci/devices/'
49 for path, dirs, files in os.walk(base_dir):
52 return os.path.join(base_dir, dir)
53 sys.exit(f"Could not find sysfs directory for device {pci}")
57 "Get the DSA instance ID using the PCI address of the device"
58 pci_dir = get_pci_dir(pci)
59 for path, dirs, files in os.walk(pci_dir):
61 if dir.startswith('dsa') and 'wq' not in dir:
63 sys.exit(f"Could not get device ID for device {pci}")
66 def configure_dsa(dsa_id, queues, prefix):
67 "Configure the DSA instance with appropriate number of queues"
68 dsa_dir = SysfsDir(f"/sys/bus/dsa/devices/dsa{dsa_id}")
70 max_groups = dsa_dir.read_int("max_groups")
71 max_engines = dsa_dir.read_int("max_engines")
72 max_queues = dsa_dir.read_int("max_work_queues")
73 max_work_queues_size = dsa_dir.read_int("max_work_queues_size")
75 nb_queues = min(queues, max_queues)
76 if queues > nb_queues:
77 print(f"Setting number of queues to max supported value: {max_queues}")
79 # we want one engine per group, and no more engines than queues
80 nb_groups = min(max_engines, max_groups, nb_queues)
81 for grp in range(nb_groups):
82 dsa_dir.write_values({f"engine{dsa_id}.{grp}/group_id": grp})
84 # configure each queue
85 for q in range(nb_queues):
86 wq_dir = SysfsDir(os.path.join(dsa_dir.path, f"wq{dsa_id}.{q}"))
87 wq_dir.write_values({"group_id": q % nb_groups,
90 "name": f"{prefix}_wq{dsa_id}.{q}",
92 "size": int(max_work_queues_size / nb_queues)})
94 # enable device and then queues
95 idxd_dir = SysfsDir(get_drv_dir("idxd"))
96 idxd_dir.write_values({"bind": f"dsa{dsa_id}"})
98 user_dir = SysfsDir(get_drv_dir("user"))
99 for q in range(nb_queues):
100 user_dir.write_values({"bind": f"wq{dsa_id}.{q}"})
104 "Main function, does arg parsing and calls config function"
105 arg_p = argparse.ArgumentParser(
106 description="Configure whole DSA device instance for DPDK use")
107 arg_p.add_argument('dsa_id',
108 help="Specify DSA instance either via DSA instance number or PCI address")
109 arg_p.add_argument('-q', metavar='queues', type=int, default=255,
110 help="Number of queues to set up")
111 arg_p.add_argument('--name-prefix', metavar='prefix', dest='prefix',
113 help="Prefix for workqueue name to mark for DPDK use [default: 'dpdk']")
114 arg_p.add_argument('--reset', action='store_true',
115 help="Reset DSA device and its queues")
116 parsed_args = arg_p.parse_args(args[1:])
118 dsa_id = parsed_args.dsa_id
119 dsa_id = get_dsa_id(dsa_id) if ':' in dsa_id else dsa_id
120 if parsed_args.reset:
123 configure_dsa(dsa_id, parsed_args.q, parsed_args.prefix)
126 if __name__ == "__main__":