1 # Copyright (c) 2024 Intel and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """DMA util library."""
17 from resources.libraries.python.topology import NodeType, Topology
18 from resources.libraries.python.ssh import exec_cmd, exec_cmd_no_error
22 """Common DMA utilities"""
25 def get_dma_resource(node, dma_device):
26 """Get DMA resource from DMA device.
28 :param node: Topology node.
29 :param dma_device: DMA device.
32 :returns: DMA resource.
36 cmd = f"grep -H . /sys/bus/pci/devices/{dma_device}/dsa*/*"
37 _, stdout, stderr = exec_cmd(node, cmd, sudo=True)
40 dma_info["dma_device"] = dma_device
41 dma_info["engine"] = list()
42 dma_info["wq"] = list()
43 dma_info["group"] = list()
45 for line in stdout.split():
46 g1 = search(r"/(dsa\d+)/(.+):(.+)", line)
48 dma_info["dma_name"] = g1.group(1)
49 dma_info[f"{g1.group(2)}"] = g1.group(3)
51 for line in stderr.split():
52 g2 = search(r"/(dsa\d+)/((engine|group|wq)\d+\.\d+)", line)
54 dev_type = g2.group(3)
56 dma_info[dev_type].append(dev)
61 def disable_dma_device(node, dma_name):
62 """Disable DMA device.
64 :param node: Topology node.
65 :param dma_name: DMA name.
69 cmd = f"cat /sys/bus/dsa/devices/{dma_name}/state"
70 stdout, _ = exec_cmd_no_error(
72 message="Failed to get dma state.")
73 if stdout.strip() == "disabled":
76 cmd = f"accel-config disable-device -f {dma_name}"
79 message="Failed to disable DMA on DUT.")
82 def enable_dma_device(node, dma_name, groups, engines, wqs, wq_size,
83 max_batch_size, max_transfer_size):
86 :param node: Topology node.
87 :param dma_name: DMA name.
88 :param groups: DMA groups.
89 :param engines: DMA engines.
90 :param wqs: DMA work queues.
91 :param wq_size: DMA work queue size.
92 :param max_batch_size: Wq max batch size.
93 :param max_transfer_size: Wq max transfer size.
100 :type max_batch_size: int
101 :type max_transfer_size: int
105 cmd = f"accel-config config-device {dma_name}"
108 node, cmd, sudo=True,
109 message="Failed to configure DMA device on DUT.")
111 # Configure DMA group
112 for i, group in enumerate(groups):
113 cmd = f"accel-config config-group " \
114 f"{dma_name}/{group} --read-buffers-reserved=0"
117 node, cmd, sudo=True,
118 message="Failed to configure DMA group on DUT.")
120 # Configure DMA engine
121 for i, engine in enumerate(engines):
122 cmd = f"accel-config config-engine " \
123 f"{dma_name}/{engine} --group-id={i}"
126 node, cmd, sudo=True,
127 message="Failed to configure DMA engine on DUT.")
129 # Configure DMA work queue
130 for i, wq in enumerate(wqs):
131 cmd = f"accel-config config-wq {dma_name}/{wq} " \
132 f" --group-id={i%len(engines)} --type=user " \
133 f" --priority=10 --block-on-fault=1 " \
134 f" --wq-size={wq_size} --mode=dedicated " \
135 f" --name={dma_name}_{i} " \
136 f" --max-batch-size={max_batch_size} " \
137 f" --max-transfer-size={max_transfer_size} "
140 node, cmd, sudo=True,
141 message="Failed to configure DMA work queue on DUT.")
143 # Enable DMA and work queues
144 cmd = f"accel-config enable-device {dma_name}"
146 node, cmd, sudo=True,
147 message="Failed to enable DMA device on DUT.")
149 dma_wqs = [f"{dma_name}/{wq}" for wq in wqs]
150 cmd = f"accel-config enable-wq {' '.join(dma_wqs)}"
152 node, cmd, sudo=True,
153 message="Failed to enable DMA work queue on DUT.")
156 def enable_dmas_and_wqs_on_dut(node, wq_num):
157 """Enable DMAs and work queues on DUT.
159 :param node: Topology node.
160 :param wq_num: Number of work queues.
163 :returns: DMA work queues enabled.
166 if node["type"] == NodeType.DUT:
167 dma_devs = Topology.get_bus(node)
171 for dev in dma_devs.values():
172 if "Intel-DSA" not in dev["model"]:
175 dev_pci = dev["pci_address"]
176 dma_info = DMAUtil.get_dma_resource(node, dev_pci)
178 dma_name = dma_info["dma_name"]
179 groups = dma_info["group"]
180 engines = dma_info["engine"]
182 wq_num_per_dma = wq_num//len(dma_devs) if wq_num > 1 else 1
183 max_transfer_size = \
184 int(dma_info["max_transfer_size"])//wq_num_per_dma
185 wq_size = int(dma_info["max_work_queues_size"])//wq_num_per_dma
186 max_batch_size = int(dma_info["max_batch_size"])
188 DMAUtil.disable_dma_device(node, dma_name)
190 DMAUtil.enable_dma_device(node,
192 groups[:wq_num_per_dma],
193 engines[:wq_num_per_dma],
194 wqs[:wq_num_per_dma],
199 enabled_wqs += wqs[:wq_num_per_dma]
201 cmd = f"lspci -vvv -s {dev_pci}"
203 node, cmd, sudo=True, message="Failed")
205 cmd = "accel-config list"
207 node, cmd, sudo=True, message="Failed")
209 cmd = "cat /proc/cmdline"
211 node, cmd, sudo=True, message="Failed")