Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ index 98035c1..7527942 100644
+++ b/VERSION
@@ -1 +1 @@
-26.03.0
+26.03.90_mtl_
+26.03.92_mtl_
diff --git a/config/meson.build b/config/meson.build
index 9ba7b9a..0d59d76 100644
--- a/config/meson.build
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MTL <mtl@example.com>
Date: Wed, 1 Jul 2026 00:00:00 -0400
Subject: [PATCH] config: default cpu_instruction_set to generic instead of
native

Building DPDK with the implicit 'auto' -> 'native' default bakes the
build host's full ISA (e.g. AVX-512) into ELF init constructors such as
dummy_queue_init() in librte_ethdev. Those constructors run at
dlopen()/exec time, before any of DPDK's own runtime CPU dispatch
(rte_cpu_get_flag_enabled(), compile_time_cpuflags) can gate on it, so
a shared library or app built on an AVX-512 host raises SIGILL the
moment it is loaded on any narrower target CPU -- this hit MTL's
GStreamer plugins when loaded via gst-inspect-1.0 on a non-AVX-512
host/VM (see .github/avx512_crash.md).

Default 'auto' to 'generic' (the portable per-arch baseline DPDK
already supports, e.g. 'corei7' on x86) instead of 'native'. This does
not remove AVX-512/AVX2 support: DPDK's own runtime CPU dispatch still
selects those code paths where it explicitly checks for them. Callers
that want the old native-optimized build can still opt back in with
-Dcpu_instruction_set=native.

Signed-off-by: MTL <mtl@example.com>
---
config/meson.build | 8 +++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/config/meson.build b/config/meson.build
--- a/config/meson.build
+++ b/config/meson.build
@@ -132,7 +132,14 @@ else
endif
if platform == 'native'
if cpu_instruction_set == 'auto'
- cpu_instruction_set = 'native'
+ # MTL: default 'auto' to the portable 'generic' baseline rather
+ # than 'native'. -march=native bakes the build host's full ISA
+ # (e.g. AVX-512) into ELF init constructors that run before any
+ # runtime CPU dispatch can gate on it, crashing with SIGILL on
+ # narrower target CPUs. Runtime dispatch still selects AVX2/
+ # AVX-512 code paths where DPDK explicitly checks for them.
+ # Pass -Dcpu_instruction_set=native to opt back in.
+ cpu_instruction_set = 'generic'
endif
endif
endif
--
2.47.3
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2026 Intel Corporation
"""Shared fixtures for avx512_compat tests.

These tests emulate a non-AVX-512 host via ``qemu-x86_64-static`` to catch
init-time SIGILL crashes caused by DPDK being built with an ISA baseline
that is wider than the CPU it eventually runs on (see
``.github/avx512_crash.md``). qemu-user is an optional resource: skip
cleanly instead of failing the suite when it cannot be made available.
"""
from __future__ import annotations

import pytest

QEMU_CACHE_PATH = "/tmp/mtl_validation_qemu-x86_64-static"
QEMU_DOWNLOAD_URL = (
"https://github.com/multiarch/qemu-user-static/releases/download/"
"v7.2.0-1/qemu-x86_64-static"
)


@pytest.fixture(scope="session")
def qemu_x86_64_static(hosts):
"""Return a path to a runnable ``qemu-x86_64-static`` binary, or skip."""
host = list(hosts.values())[0]

found = host.connection.execute_command(
"command -v qemu-x86_64-static", shell=True, expected_return_codes=None
)
if found.return_code == 0 and found.stdout.strip():
return found.stdout.strip()

cached = host.connection.execute_command(
f"test -x {QEMU_CACHE_PATH}", shell=True, expected_return_codes=None
)
if cached.return_code == 0:
return QEMU_CACHE_PATH

downloaded = host.connection.execute_command(
f"curl -fsSL -o {QEMU_CACHE_PATH} {QEMU_DOWNLOAD_URL} "
f"&& chmod +x {QEMU_CACHE_PATH}",
shell=True,
expected_return_codes=None,
)
if downloaded.return_code == 0:
return QEMU_CACHE_PATH

pytest.skip(
"qemu-x86_64-static unavailable (not on PATH and download failed) - "
"install the 'qemu-user-static' package or see .github/avx512_crash.md "
"for a manual download command"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2026 Intel Corporation
"""GStreamer plugin AVX-512 compatibility.

Regression test for the crash described in ``.github/avx512_crash.md``:
DPDK built with an ISA baseline wider than the target CPU bakes AVX-512
instructions into ELF constructors (e.g. ``dummy_queue_init`` in
``librte_ethdev.so``) that run unconditionally at ``dlopen()`` time,
crashing with SIGILL on hosts/VMs that lack AVX-512 -- with no way for
MTL's own runtime SIMD dispatch to intervene, since the crash happens
before any MTL code runs.

The non-AVX-512 host is emulated locally with ``qemu-x86_64-static`` using
``QEMU_CPU=Skylake-Client`` (AVX2, no AVX-512; also satisfies glibc's
x86-64-v2 baseline, unlike older QEMU CPU models such as ``qemu64``).
"""

import pytest
from mtl_engine.execute import log_fail

GSTREAMER_PLUGINS = [
"libgstmtl_st20p_rx.so",
"libgstmtl_st20p_tx.so",
"libgstmtl_st30p_rx.so",
"libgstmtl_st30p_tx.so",
"libgstmtl_st40p_rx.so",
"libgstmtl_st40p_tx.so",
"libgstmtl_st40_rx.so",
]


@pytest.mark.smoke
@pytest.mark.parametrize("plugin", GSTREAMER_PLUGINS)
def test_gstreamer_plugin_avx512_compat(hosts, mtl_path, qemu_x86_64_static, plugin):
host = list(hosts.values())[0]
plugin_path = f"{mtl_path}/.local_install/gstreamer/gstreamer-1.0/{plugin}"
ld_library_path = (
f"{mtl_path}/.local_install/mtl/lib64:" f"{mtl_path}/.local_install/dpdk/lib64"
)

if (
host.connection.execute_command(
f"test -f {plugin_path}", shell=True, expected_return_codes=None
).return_code
!= 0
):
pytest.skip(f"GStreamer plugin not built: {plugin_path}")

native = host.connection.execute_command(
f"LD_LIBRARY_PATH={ld_library_path} gst-inspect-1.0 {plugin_path}",
shell=True,
expected_return_codes=None,
)
if native.return_code != 0:
log_fail(f"Native gst-inspect-1.0 failed for {plugin}: {native.stdout}")
assert native.return_code == 0, f"Native load of {plugin} failed unexpectedly"

emulated = host.connection.execute_command(
f"LD_LIBRARY_PATH={ld_library_path} QEMU_CPU=Skylake-Client "
f"{qemu_x86_64_static} $(command -v gst-inspect-1.0) {plugin_path}",
shell=True,
expected_return_codes=None,
)
if emulated.return_code != 0:
log_fail(
f"{plugin} crashed under emulated non-AVX-512 CPU "
f"(rc={emulated.return_code}): {emulated.stdout}"
)
assert emulated.return_code == 0, (
f"{plugin} must load on a non-AVX-512 CPU without SIGILL "
f"(rc={emulated.return_code}, expected 132 before the DPDK ISA-baseline fix)"
)
2 changes: 1 addition & 1 deletion versions.env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
DPDK_VER=26.03
DPDK_MTL_MINOR_VER=90
DPDK_MTL_MINOR_VER=92
ICE_VER=2.6.6
ICE_DMID=921605
ONE_API_GPU_VER=1.22.3
Expand Down
Loading