Skip to content

topology2: validator: add a tool to check topology validity at build time - #11344

Open
kv2019i wants to merge 4 commits into
thesofproject:mainfrom
kv2019i:202610-tplg-validator-tool
Open

kv2019i wants to merge 4 commits into
thesofproject:mainfrom
kv2019i:202610-tplg-validator-tool

Conversation

@kv2019i

@kv2019i kv2019i commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator

Prompted by recent bugs in topology2 files (e.g. #11258 ), here's a PR that adds a build time tool that checks generated topology files against expectations of the Linux kernel SOF driver. The tool tries to cover common errors alsatplg tool doesnt' cover, and to give more understanable error messages when problems are seen.

The tool is designed such we can have it run for every topology build, and also run standalone when debugging specific issues.

Add the foundation for an offline validator of SOF IPC4 topology
binaries.

tplgparse/binary.py describes the ALSA topology binary format (ABI 5)
with construct. The record layouts are ported from sof-test
tools/tplgtool2.py, but the section walk mirrors soc_tplg_load() in
the kernel so that malformed input is reported as an issue with a file
offset instead of a parser exception. DAI and DAI link sections are
parsed too, and all values are kept as plain integers.

tplgparse/model.py provides a typed view of widgets, kcontrols,
routes, PCMs and links, with vendor tuples decoded by the type of the
vendor array they are in.

The Linux SOF driver is the reference for how a topology is read.
Instead of hand copying its token lists, schema/gen_kernel_tokens.py
extracts from a kernel tree the SOF_TKN_* IDs, the
struct sof_topology_token tables with their token types, the token
lists of tplg_ipc4_widget_ops, the DAI type names and the kcontrol
handler IDs into schema/kernel_tokens.py. With --check it reports drift
against a kernel tree.

tplgparse/kernel_engine.py emulates the kernel tuple engine
(sof_parse_token_sets(), sof_copy_tuples(), sof_update_ipc_object(),
sof_widget_parse_tokens()) on top of the generated tables. The kernel
does not always read tuples the way a topology means them: multiple
token sets are filled by occurrence count, parsing stops once enough
tokens are found and sof_copy_tuples() picks the element layout from
the expected token type, not from the vendor array type. Every value
read is recorded with its source offset so that checks can compare the
kernel view to the intended one.

kernel_tokens.py is generated from sof-dev at commit 5c16bd4ee077

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Add tplg_validate.py, which checks topology binaries against what the
Linux SOF driver does when loading them, so that problems are found
without the target hardware. Rules are grouped in layers:

 L1  binary structure as checked by sound/soc/soc-topology.c: headers,
     element sizes, NUL terminated names, widget types, enum items,
     TLV types and kcontrol handler binding
 L2  vendor tuples as read by the emulated SOF tuple engine: kernel
     parse errors, values read from the wrong tuple, malformed vendor
     arrays, unknown tokens, tuple types the kernel ignores, and audio
     format blocks versus NUM_INPUT/OUTPUT_AUDIO_FORMATS
 L3  IPC4 load and setup rules from topology.c and ipc4-topology.c:
     route endpoints, scheduler widgets, chain DMA, volatile controls
     in dynamic pipelines, audio formats, module UUIDs, DAI types, pin
     counts and bindings, volume and bytes controls, PCM to host copier
     binding, BE link configs and the manifest
 L4  PCM path walk and host copier format matching (advisory)

Each finding names the rule and the kernel function it follows, and
--list-rules prints them all for review against kernel changes.
Errors mean the kernel fails to load the topology or to use a PCM,
warnings are likely mistakes or failures that depend on runtime state.
The exit status is non-zero on errors, or on warnings with --werror.

known-issues.txt lists errors present in the current topologies, which
--waivers reports as warnings, so that the build can enforce the rules
for new problems while the existing ones are fixed.

schema/check_tokens_conf.py cross-checks topology2 tokens.conf and the
token_ref attributes of the classes against the kernel schema.

The pytest suite builds small topologies with tests/tplgbuild.py and
has a passing and failing case for each rule. Integration tests build
real topology2 targets with alsatplg and, with KERNEL_TREE set, check
the token schema against a kernel tree.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
alsatplg accepts many topologies that the SOF driver rejects at load
time, e.g. it reports a route to an undefined widget but still exits
successfully. Such problems are usually only found on target hardware.

Run tools/topology/validator/tplg_validate.py after alsatplg for every
topology2 target. A validation error fails the target and deletes the
.tplg so that it is checked again on the next build. Errors listed in
validator/known-issues.txt are reported as warnings.

Validation is enabled by default with the TPLG_VALIDATE option and is
skipped with a warning when python3 with the construct module is not
available.

Document the validator and point to it from the topology READMEs.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Install python3-construct in the tools workflow so that the topology
build validates every topology2 binary, and run the validator pytest
suite after the build.

Add a weekly workflow that checks the validator kernel token schema
against the SOF driver in thesofproject/linux topic/sof-dev, so that
token table changes in the kernel are noticed.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>

@lgirdwood lgirdwood left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Input-handling, validation-accuracy, and incremental-build dependency issues remain unresolved.

7 open issues
What changed in this PR

Adds an offline SOF IPC4 topology validator to catch kernel-facing errors during topology2 builds, complementing checks performed by alsatplg.

Changes:

  • Adds binary parsing, kernel token emulation, and layered validation rules.
  • Integrates validation into topology2 builds with waivers for known issues.
  • Adds tests, schema drift checks, and usage documentation.
File Description
tools/​topology/​validator/​tplgparse/​model.py Models parsed topology objects and vendor tuples.
tools/​topology/​validator/​tplgparse/​kernel_engine.py Emulates kernel token parsing.
tools/​topology/​validator/​tplgparse/​binary.py Parses ALSA topology binary structures.
tools/​topology/​validator/​tplgparse/​__init__.py Initializes the parser package.
tools/​topology/​validator/​tplg_validate.py Provides the CLI, reporting, and waiver handling.
tools/​topology/​validator/​tests/​tplgbuild.py Builds synthetic topology fixtures.
tools/​topology/​validator/​tests/​test_rules.py Tests validation rules.
tools/​topology/​validator/​tests/​test_integration.py Tests real topologies, CLI behavior, and schema drift.
tools/​topology/​validator/​tests/​conftest.py Configures test imports.
tools/​topology/​validator/​schema/​kernel_tokens.py Supplies generated kernel token tables.
tools/​topology/​validator/​schema/​gen_kernel_tokens.py Generates and checks the kernel schema.
tools/​topology/​validator/​schema/​check_tokens_conf.py Cross-checks topology2 token definitions.
tools/​topology/​validator/​schema/​__init__.py Initializes the schema package.
tools/​topology/​validator/​README.md Documents usage, design, and maintenance.
tools/​topology/​validator/​known-issues.txt Records existing validation waivers.
tools/​topology/​validator/​checks/​tokens.py Checks vendor tuples and format counts.
tools/​topology/​validator/​checks/​structure.py Checks binary structure and control metadata.
tools/​topology/​validator/​checks/​paths.py Checks PCM paths and format compatibility.
tools/​topology/​validator/​checks/​ipc4.py Checks IPC4 setup requirements.
tools/​topology/​validator/​checks/​__init__.py Registers and runs validation rules.
tools/​topology/​topology2/​README.md Documents build-time validation.
tools/​topology/​README.md Introduces the validator in the topology overview.
tools/​topology/​CMakeLists.txt Runs validation after topology2 compilation.
.github/​workflows/​tplg-validator-schema.yml Adds scheduled kernel schema checks.
.github/​workflows/​tools.yml Installs dependencies and runs validator tests.

Review effort: Balanced

if array_size < 0:
raise KernelError(f"invalid vendor array size 0x{asize:x}", ref)

for i in range(num):
The n-th occurrence of a token lands in set n, regardless of which
format block it came from in the topology.
"""
sets = [{} for _ in range(max(instances, 1))]
Comment on lines +120 to +123
set(tplg_validate_command COMMAND ${Python3_EXECUTABLE} ${TPLG_VALIDATOR}
--quiet --remove-on-error
--waivers ${TPLG_VALIDATE_WAIVERS}
${output_name}.tplg)
yield c.label, f"{b.num_channels} channels, maximum is {MAX_CHAN}"
if lo > hi or hi >= INT_MAX:
yield c.label, f"invalid range min {lo} max {hi}"
elif hi > 1:
return
if len(data) <= SOF_IPC4_TPLG_ABI_SIZE:
return
_maj, _min, _patch, count = struct.unpack_from("<HHHH", data)
Comment on lines +147 to +151
blocks = [{t.token: t.value for t in a.tuples} for a in w.priv.arrays
if any(t.token == rate_token for t in a.tuples)]
if len(blocks) < num:
yield w.label, (f"declares {num} {direction} formats but defines "
f"{len(blocks)}"), ERROR
Comment on lines +164 to +166
used = [describe(b, rate_token) for b in blocks[:num]]
ignored = [describe(b, rate_token) for b in blocks[num:]]
new = sorted(set(ignored) - set(used))
@intel-sofci

Copy link
Copy Markdown

PR 11344: test results

Run date: 2026-10-23 11:44 UTC

Tested commit: 4890c288113ef7a2742f91ca0976151e38ef43d6

mtl pass rate lnl pass rate ptl pass rate wcl pass rate nvl pass rate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants