From: Adam Miszczak <adam.miszczak@linux.intel.com>
To: igt-dev@lists.freedesktop.org
Cc: marcin.bernatowicz@linux.intel.com, kamil.konieczny@linux.intel.com
Subject: [PATCH i-g-t 04/10] tools/vmtb: Extend IGT and WSIM abstractions
Date: Tue, 24 Feb 2026 08:50:21 +0100 [thread overview]
Message-ID: <20260224075027.2409675-5-adam.miszczak@linux.intel.com> (raw)
In-Reply-To: <20260224075027.2409675-1-adam.miszczak@linux.intel.com>
Introduce few improvements to IGT and gem_wsim executors:
1. Add gem_wsim workload descriptor resources config
In order to place workload files in a common resources directory,
extend VMTB config with a relevant entry and read the path in a conftest.
Implement capability for device specific workload files in wsim resources
directory (as different GPU devices may have various sets of engines).
Wsim device specific path format looks as follows:
[vmtb_root_path]/vmm_flows/resources/wsim/[device_name_abbr]/[wl_desc].wsim
e.g.:
- resources/wsim/ptl/wl.wsim
- resources/wsim/bmg/wl.wsim
2. Support gem_wsim workload files on VM
So far GemWsim was initialized with a simple string workload descriptor
passed with '-w <workload>' option.
However, multiple complex workloads are expected for a busy VF migration
scenarios - therefore it would be handy to define it as workload files.
Gem_wsim input files will be deployed as VMTB resources on a host,
whereas we want to execute it on VM as well.
Hence, content of the wsim workload file is copied to /tmp on a guest/host
and executed from that location.
In case of the host, original (resources) location will work
as a wsim file input, however temp file is still used for simplicity
and consistency (to avoid instance type checks).
3. Add IGT and WSIM results check function
Extend IgtExecutor and GemWsim with new check_results() method to allow
object-oriented approach for checking IGT/WSIM results and unify interfaces.
Existing helper - igt_check(IgtExecutor) is still supported,
but IgtExecutor.check_results() is now preferred.
Also, implement IgtExecutor's is_running() (similarly to GemWsim)
and keep the process state (ProcessResult).
Introduced change simplifies supporting both IGT and gem_wsim workloads
in busy migration tests.
4. Support IGT tests repeated execution
Few planned VF busy migration scenarios require executing short IGT tests
in a longer time slot (in a loop).
To achieve it, allow IgtExecutor to accept expected number of IGT test
repeats and reflect it in a testlist passed to the igt_runner
(multiply requested test entries).
By default, IgtExecutor's 'num_repeats' input parameter is set to 1,
so in the usual case (single IGT execution) it doesn't need to be
explicitly provided.
Signed-off-by: Adam Miszczak <adam.miszczak@linux.intel.com>
---
tools/vmtb/bench/configurators/vmtb_config.py | 4 +-
tools/vmtb/bench/executors/gem_wsim.py | 45 +++++++++++++++----
tools/vmtb/bench/executors/igt.py | 36 ++++++++++++---
tools/vmtb/bench/machines/physical/device.py | 2 +-
tools/vmtb/vmm_flows/conftest.py | 8 +++-
tools/vmtb/vmtb_config.json | 1 +
6 files changed, 78 insertions(+), 18 deletions(-)
diff --git a/tools/vmtb/bench/configurators/vmtb_config.py b/tools/vmtb/bench/configurators/vmtb_config.py
index 49dde4589..8fd2b87d5 100644
--- a/tools/vmtb/bench/configurators/vmtb_config.py
+++ b/tools/vmtb/bench/configurators/vmtb_config.py
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: MIT
-# Copyright © 2024 Intel Corporation
+# Copyright © 2024-2026 Intel Corporation
import json
import logging
@@ -40,6 +40,7 @@ class VmtbConfig:
host_config: VmtbHostConfig
guest_config: VmtbGuestConfig
vgpu_profiles_path: str
+ wsim_wl_path: str
guc_ver_path: str
ci_host_dmesg_file: str
@@ -104,6 +105,7 @@ class VmtbConfigJsonReader:
host_config=vmtb_host_config,
guest_config=vmtb_guest_config,
vgpu_profiles_path=config_json['resources']['vgpu_profiles_path'],
+ wsim_wl_path=config_json['resources']['wsim_wl_path'],
guc_ver_path=config_json['resources']['guc_ver_path'],
ci_host_dmesg_file=config_json['ci']['host_dmesg_file'])
diff --git a/tools/vmtb/bench/executors/gem_wsim.py b/tools/vmtb/bench/executors/gem_wsim.py
index 46fa2291c..0cdfcc7e4 100644
--- a/tools/vmtb/bench/executors/gem_wsim.py
+++ b/tools/vmtb/bench/executors/gem_wsim.py
@@ -1,9 +1,10 @@
# SPDX-License-Identifier: MIT
-# Copyright © 2024 Intel Corporation
+# Copyright © 2024-2026 Intel Corporation
import logging
import re
import typing
+from pathlib import Path
from bench import exceptions
from bench.executors.shell import ShellExecutor
@@ -23,13 +24,28 @@ PREEMPT_10MS_WORKLOAD = (f'1.DEFAULT.{int(ONE_CYCLE_DURATION_MS * 1000 / 2)}.0.0
NON_PREEMPT_10MS_WORKLOAD = f'X.1.0,X.2.0,{PREEMPT_10MS_WORKLOAD}'
class GemWsim(ShellExecutor):
- def __init__(self, machine: MachineInterface, num_clients: int = 1, num_repeats: int = 1,
- workload: str = PREEMPT_10MS_WORKLOAD, timeout: int = DEFAULT_TIMEOUT) -> None:
- super().__init__(
- machine,
- f'/usr/local/libexec/igt-gpu-tools/benchmarks/gem_wsim -w {workload} -c {num_clients} -r {num_repeats}',
- timeout)
- self.machine_id = str(machine)
+ def __init__(self, target: MachineInterface,
+ num_clients: int = 1,
+ num_repeats: int = 1,
+ workload: str = PREEMPT_10MS_WORKLOAD,
+ timeout: int = DEFAULT_TIMEOUT) -> None:
+
+ self.machine_id = str(target)
+ wl_file_path = Path(workload)
+
+ if wl_file_path.is_file():
+ # Copy workload descriptor from the source host file
+ # to the requested target machine (VM or host)
+ workload = '/tmp/igt_workload.wsim'
+ wl_desc = wl_file_path.read_text(encoding='utf-8')
+ target.write_file_content(workload, wl_desc)
+
+ logger.debug("IGT/wsim workload descriptor:\n%s", wl_desc)
+
+ wsim_path = Path(target.get_igt_config().test_dir) / 'benchmarks' / 'gem_wsim'
+ command = f'{wsim_path} -w {workload} -c {num_clients} -r {num_repeats}'
+
+ super().__init__(target, command, timeout)
def __str__(self) -> str:
return f'gem_wsim({self.machine_id}:{self.pid})'
@@ -49,6 +65,19 @@ class GemWsim(ShellExecutor):
raise exceptions.GemWsimError(f'{self}: exit_code: {proc_result.exit_code}'
f' stdout: {proc_result.stdout} stderr: {proc_result.stderr}')
+ def check_results(self) -> bool:
+ """Verify gem_wsim execution results. Return True for workload success, False on fail."""
+ # TODO: support also checking wsim workload: 'Verify Xe spinner batch completion'
+ try:
+ wl_results: GemWsimResult = self.wait_results()
+ except exceptions.GemWsimError as exc:
+ logger.error("[%s] WSIM failed: %s", self.target, exc)
+ return False
+
+ logger.debug("[%s] WSIM passed in %ss (%s WL/s)",
+ self.target, wl_results.elapsed_sec, wl_results.workloads_per_sec)
+ return True
+
def gem_wsim_parallel_exec_and_check(vms: typing.List[MachineInterface], workload: str, iterations: int,
expected: typing.Optional[GemWsimResult] = None) -> GemWsimResult:
diff --git a/tools/vmtb/bench/executors/igt.py b/tools/vmtb/bench/executors/igt.py
index 4296464c2..a08f71d54 100644
--- a/tools/vmtb/bench/executors/igt.py
+++ b/tools/vmtb/bench/executors/igt.py
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: MIT
-# Copyright © 2024 Intel Corporation
+# Copyright © 2024-2026 Intel Corporation
import enum
import json
@@ -34,6 +34,7 @@ igt_tests: typing.Dict[IgtType, typing.Tuple[str, str]] = {
class IgtExecutor(ExecutorInterface):
def __init__(self, target: MachineInterface,
test: typing.Union[str, IgtType],
+ num_repeats: int = 1,
timeout: int = DEFAULT_TIMEOUT) -> None:
self.igt_config = target.get_igt_config()
@@ -46,18 +47,25 @@ class IgtExecutor(ExecutorInterface):
self.results: typing.Dict[str, typing.Any] = {}
self.target: MachineInterface = target
self.igt: str = test if isinstance(test, str) else self.select_igt_variant(target.get_drm_driver_name(), test)
- self.target.write_file_content(testlist, self.igt)
- self.timeout: int = timeout
logger.info("[%s] Execute IGT test: %s", target, self.igt)
+ if num_repeats > 1:
+ logger.debug("Repeat IGT execution %s times", num_repeats)
+ self.igt = (self.igt + '\n') * num_repeats
+
+ self.target.write_file_content(testlist, self.igt)
+ self.timeout: int = timeout
+ self.proc_result = ProcessResult()
self.pid: int = self.target.execute(command)
# Executor interface implementation
def status(self) -> ProcessResult:
- return self.target.execute_status(self.pid)
+ self.proc_result = self.target.execute_status(self.pid)
+ return self.proc_result
def wait(self) -> ProcessResult:
- return self.target.execute_wait(self.pid, self.timeout)
+ self.proc_result = self.target.execute_wait(self.pid, self.timeout)
+ return self.proc_result
def sendsig(self, sig: signal.Signals) -> None:
self.target.execute_signal(self.pid, sig)
@@ -69,9 +77,25 @@ class IgtExecutor(ExecutorInterface):
self.sendsig(signal.SIGKILL)
# IGT specific methods
+ def is_running(self) -> bool:
+ return not self.status().exited
+
+ def check_results(self) -> bool:
+ """Verify IGT test results. Return True for test success, False on fail."""
+ if not self.proc_result.exited:
+ self.proc_result = self.wait()
+
+ if self.proc_result.exit_code == 0 and self.did_pass():
+ logger.debug("[%s] IGT passed", self.target)
+ return True
+
+ logger.error("[%s] IGT failed: %s", self.target, self.proc_result)
+ return False
+
def get_results_log(self) -> typing.Dict:
# Results are cached
if self.results:
+ logger.debug("Get available IGT results from cache")
return self.results
path = posixpath.join(self.igt_config.result_dir, 'results.json')
result = self.target.read_file_content(path)
@@ -95,7 +119,7 @@ class IgtExecutor(ExecutorInterface):
continue
fail_case = fail_case + aggregate[key]
- logger.debug('Full IGT test results:\n%s', json.dumps(results, indent=4))
+ logger.debug("[%s] Full IGT test results:\n%s", self.target, json.dumps(results, indent=4))
if fail_case > 0:
logger.error('Test failed!')
diff --git a/tools/vmtb/bench/machines/physical/device.py b/tools/vmtb/bench/machines/physical/device.py
index 887f607e4..a487c0e5f 100644
--- a/tools/vmtb/bench/machines/physical/device.py
+++ b/tools/vmtb/bench/machines/physical/device.py
@@ -45,7 +45,7 @@ class Device(DeviceInterface):
def __init__(self, bdf: str, driver: str) -> None:
self.pci_info = self.PciInfo(bdf)
- self.gpu_model: str = pci.get_gpu_model(self.pci_info.devid)
+ self.gpu_model = pci.get_gpu_model(self.pci_info.devid)
self.driver: DriverInterface = self.instantiate_driver(driver, self.pci_info.minor_number)
def __str__(self) -> str:
diff --git a/tools/vmtb/vmm_flows/conftest.py b/tools/vmtb/vmm_flows/conftest.py
index 3bfac01c4..28c0b5f00 100644
--- a/tools/vmtb/vmm_flows/conftest.py
+++ b/tools/vmtb/vmm_flows/conftest.py
@@ -79,8 +79,6 @@ class VmmTestingSetup:
self.guest_os_image = vmtb_config.get_guest_config().os_image_path if cmdline_config['vm_image'] is None \
else cmdline_config['vm_image']
- self.vgpu_profiles_dir = vmtb_config.vmtb_config_file.parent / vmtb_config.config.vgpu_profiles_path
-
self.host.drm_driver_name = vmtb_config.get_host_config().driver
self.host.igt_config = vmtb_config.get_host_config().igt_config
@@ -103,6 +101,12 @@ class VmmTestingSetup:
self.get_dut().driver.get_name(),
vf_migration_support)
+ vmtb_root_path = vmtb_config.vmtb_config_file.parent
+ self.vgpu_profiles_dir = vmtb_root_path / vmtb_config.config.vgpu_profiles_path
+ # Device specific wsim descriptors directory path, e.g.:
+ # [vmtb_root]/vmm_flows/resources/wsim/ptl (last subdir is lowercase key/name from pci.GpuModel class)
+ self.wsim_wl_dir = vmtb_root_path / vmtb_config.config.wsim_wl_path / self.get_dut().gpu_model.name.lower()
+
self.vgpu_profile: VgpuProfile = self.get_vgpu_profile()
# Start maximum requested number of VMs, but not more than VFs supported by the given vGPU profile
diff --git a/tools/vmtb/vmtb_config.json b/tools/vmtb/vmtb_config.json
index 640a64123..2b8fb43f3 100644
--- a/tools/vmtb/vmtb_config.json
+++ b/tools/vmtb/vmtb_config.json
@@ -23,6 +23,7 @@
},
"resources": {
"vgpu_profiles_path": "vmm_flows/resources/vgpu_profiles",
+ "wsim_wl_path": "vmm_flows/resources/wsim",
"guc_ver_path": "vmm_flows/resources/guc"
},
"ci": {
--
2.39.1
next prev parent reply other threads:[~2026-02-24 8:23 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-24 7:50 [PATCH i-g-t 00/10] vmtb: Modernize SR-IOV VM Test Bench core Adam Miszczak
2026-02-24 7:50 ` [PATCH i-g-t 01/10] tools/vmtb: Update QEMU parameters Adam Miszczak
2026-03-10 10:22 ` Bernatowicz, Marcin
2026-02-24 7:50 ` [PATCH i-g-t 02/10] tools/vmtb: Fix DUT selection based on card index Adam Miszczak
2026-03-10 10:26 ` Bernatowicz, Marcin
2026-02-24 7:50 ` [PATCH i-g-t 03/10] tools/vmtb: Fix VM snapshot query handling Adam Miszczak
2026-03-10 10:29 ` Bernatowicz, Marcin
2026-02-24 7:50 ` Adam Miszczak [this message]
2026-03-10 10:36 ` [PATCH i-g-t 04/10] tools/vmtb: Extend IGT and WSIM abstractions Bernatowicz, Marcin
2026-02-24 7:50 ` [PATCH i-g-t 05/10] tools/vmtb: VF auto/fair provisioning support Adam Miszczak
2026-03-10 10:38 ` Bernatowicz, Marcin
2026-02-24 7:50 ` [PATCH i-g-t 06/10] tools/vmtb: Refactor driver interfaces Adam Miszczak
2026-03-10 10:43 ` Bernatowicz, Marcin
2026-02-24 7:50 ` [PATCH i-g-t 07/10] tools/vmtb: Introduce VirtualDevice class Adam Miszczak
2026-03-10 10:45 ` Bernatowicz, Marcin
2026-02-24 7:50 ` [PATCH i-g-t 08/10] tools/vmtb: Redesign VirtualMachine class Adam Miszczak
2026-03-10 10:47 ` Bernatowicz, Marcin
2026-02-24 7:50 ` [PATCH i-g-t 09/10] tools/vmtb: Support max VFs configuration Adam Miszczak
2026-03-10 10:52 ` Bernatowicz, Marcin
2026-02-24 7:50 ` [PATCH i-g-t 10/10] tools/vmtb: Platform enabling: PTL and BMG support Adam Miszczak
2026-03-10 10:52 ` Bernatowicz, Marcin
2026-02-24 11:49 ` ✓ Xe.CI.BAT: success for vmtb: Modernize SR-IOV VM Test Bench core Patchwork
2026-02-24 12:43 ` ✓ i915.CI.BAT: " Patchwork
2026-02-24 16:27 ` ✗ i915.CI.Full: failure " Patchwork
2026-02-24 20:21 ` ✗ Xe.CI.FULL: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260224075027.2409675-5-adam.miszczak@linux.intel.com \
--to=adam.miszczak@linux.intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=kamil.konieczny@linux.intel.com \
--cc=marcin.bernatowicz@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox