Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debug module framework #9787

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

marcinszkudlinski
Copy link
Contributor

Tester module is a framework for a runtime testing
that need a special internal code i.e. provide an extra
load to CPU by running additional thread, etc.

The idea is to allow testing of special cases
using a standard "production" build. The module should
be compiled as a loadable module only, as it is not needed
in any real production case.

In order to keep only one testing module (in meaning of
a SOF module with separate UUID), a framework is introduced,
where a test to be executed is selected by IPC parameter

@dbaluta dbaluta changed the title Debug module farmework Debug module framework Jan 21, 2025
EXPORT_SYMBOL(source_to_sink_copy);
EXPORT_SYMBOL(source_drop_data);
Copy link
Collaborator

Choose a reason for hiding this comment

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

please place each EXPORT_SYMBOL() under respective function

Copy link
Collaborator

Choose a reason for hiding this comment

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

@marcinszkudlinski let's keep "unresolved" until actually resolved or at least explained why you the existing version is preferred

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, I see it has been moved, it is now at the end of source_drop_data function, isn't it?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@marcinszkudlinski sorry for not explaining clearly. Every EXPORT_SYMBOL() should immediately follow the respective function. Like

void f1()
{
}
EXPORT_SYMBOL(f1);

void f2()
{
}
EXPORT_SYMBOL(f2);

etc. See https://github.com/thesofproject/sof/actions/runs/12891822335/job/35944645332?pr=9787 :

WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable
#87: FILE: src/audio/sink_source_utils.c:134:
+EXPORT_SYMBOL(sink_fill_with_silence);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Confusing, because I fixed it and in the PR it is exactly as you wrote :)
...except one detail, I put the fix in wrong commit,
ok, will fix

src/audio/module_adapter/module_adapter.c Outdated Show resolved Hide resolved

SOF_DEFINE_REG_UUID(tester);

DECLARE_TR_CTX(tester_tr, SOF_UUID(tester_uuid), LOG_LEVEL_INFO);
Copy link
Collaborator

Choose a reason for hiding this comment

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

since you only want this as a module, maybe add a check that CONFIG_COMP_TESTER_MODULE is defined somewhere:

#if !CONFIG_COMP_TESTER_MODULE
#error only modular
#endif

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I want it to be modular only for production, but I still prefer to be able to compile it as built-in - it is easier to have one binary in case of debugging.


if (bs != sizeof(struct tester_init_config))
{
comp_err(dev, "tester_init(): Invalid config");
Copy link
Collaborator

Choose a reason for hiding this comment

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

please drop all function names from logs

if (cd->tester_case_interface->prepare)
ret = cd->tester_case_interface->prepare(cd->test_case_ctx, mod,
sources, num_of_sources,
sinks, num_of_sinks);
Copy link
Collaborator

Choose a reason for hiding this comment

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

since this pattern is repeated multiple times, how about

if (cd->tester_case_interface->x)
    return cd->tester_case_interface->x(...);

return 0;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

repeated, but not always - see "trigger" and "free". I believe this framework will evolve with needs etc. So I used same pattern everywhere

src/debug/tester/tester.c Outdated Show resolved Hide resolved
src/debug/tester/tester_dummy_test.c Outdated Show resolved Hide resolved
zephyr/CMakeLists.txt Show resolved Hide resolved
return 0;
if (size > sink_get_free_size(sink))
return -ENOSPC;

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would say EINVAL here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it is the same as in source_to_sink_copy - NO_SPACE error if somebody wants to copy/fill more than available space in destination

src/audio/sink_source_utils.c Show resolved Hide resolved
src/audio/sink_source_utils.c Show resolved Hide resolved
app/boards/intel_adsp_ace15_mtpm.conf Show resolved Hide resolved
src/audio/module_adapter/module_adapter.c Outdated Show resolved Hide resolved
@dbaluta
Copy link
Collaborator

dbaluta commented Jan 21, 2025

Do you also have a topology file for this? It is not yet clear to me how the component is created and used.

@marcinszkudlinski
Copy link
Contributor Author

@dbaluta in internal CI test. No topology needed.

@marcinszkudlinski
Copy link
Contributor Author

I think you can export this into a separate patch, as it is not related to this change.

it is, the symbol is needed now in a loadable module. Anyway, separate commit does not hurt

@marcinszkudlinski marcinszkudlinski force-pushed the debug_module_farmework branch 3 times, most recently from 4f74e6f to 06b7610 Compare January 21, 2025 16:51
Copy link
Member

@lgirdwood lgirdwood left a comment

Choose a reason for hiding this comment

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

@marcinszkudlinski what will the flow be to use the tester ? i.e. how will a developer enable tester and how will it be inserted into pipelines ?

src/debug/tester/tester.c Show resolved Hide resolved
Copy link
Collaborator

@kv2019i kv2019i left a comment

Choose a reason for hiding this comment

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

This seems like a cool idea! A few notes inline about how this is explained/named. I think having fake/test/synthetic modules in audio frameworks is a widely used and well understood concept, so I think the descriptions could be in simpler language.

I think the big design question is do we lumb all possible test modules in single one, or do separate modules per type of test (e.g. audio-error-injector could be separate from load-generation). If there's any chance of the latter, then I'd stop for a second to think about naming as "tester" is very generic.

No blockers in the end though.

@@ -11,6 +11,7 @@ CONFIG_COMP_CHAIN_DMA=y
CONFIG_COMP_CROSSOVER=y
Copy link
Collaborator

Choose a reason for hiding this comment

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

I had to read the commit a few times, then code, and then again the commit, to understand what this is about. I think what confuses is the generic "tester framework" language. I'd actually not use the term "framework" here. IOW, in the end you are adding an audio module that happens to be implemented in a way that allows for easy extension. It would be maybe easier to understand if you just write: "Tester is an audio module that can be configured via module IPC to perform various test functions."

I also wonder about the "tester" name. It is very generic. To add something specific (like load generation), a "loadgen" module would be more descriptive, but I guess you want to keep this generic on purpose.

Copy link
Collaborator

@dbaluta dbaluta Jan 22, 2025

Choose a reason for hiding this comment

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

@kv2019i agree with you. I'm still yet to go back and do re-read the code to understand what this is all about. The naming is unfortunate.

app/configs/mtl/modules.conf Show resolved Hide resolved
default n
depends on IPC_MAJOR_4
help
Select for loadable module for testing
Copy link
Collaborator

Choose a reason for hiding this comment

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

Given the very generic name, and a new type of module, I think this warrants a bit more text to describe (i.e. the text you have in the git commti).

And here "loadable" confuses me a bit. Any module can be loadable, so isn't this just a test module.

#include "tester_dummy_test.h"

/**
* Tester module is a framework for a runtime testing that need a special internal code
Copy link
Collaborator

Choose a reason for hiding this comment

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

"special internal code" -> "test code" ?

Add "sink_fill_with_silence" and "source_drop_data" tools
for sink/source. The tools will respectively drop given
amount of data from source or fill sink witj silence.

To be used when a module doesn't want to process data at
the moment, but still needs to consume data at input and
provide something at output

Signed-off-by: Marcin Szkudlinski <[email protected]>
module_adapter_set_state will be needed in loadable
debug module framework

Signed-off-by: Marcin Szkudlinski <[email protected]>
Tester module is a framework for a runtime testing
that need a special internal code i.e. provide an extra
load to CPU by running additional thread, etc.

The idea is to allow testing of special cases
using a standard "production" build. The module should
be compiled as a loadable module only, as it is not needed
in any real production case.

In order to keep only one testing module (in meaning of
a SOF module with separate UUID), a framework is introduced,
where a test to be executed is selected by IPC parameter

Signed-off-by: Marcin Szkudlinski <[email protected]>
the debug module is intended to be a place for a test code
for continuous integration testing, performed on a standard
"production" build
The test code, however, should not be loaded on any of the
target platforms, therefore debug module is compiled as a
LLEXT loadable

Signed-off-by: Marcin Szkudlinski <[email protected]>
if (cd->tester_case_interface->init)
ret = cd->tester_case_interface->init(mod, &cd->test_case_ctx);

if (ret) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nitpick: I'd move this under the if in line 88 above - ret can become non-zero only there.

@@ -54,6 +54,7 @@ e87bf747-e574-4362-bf2cc015d2859dd9 clkdrv_mt8196
c2b00d27-ffbc-4150-a51a245c79c5e54b dai
06711c94-d37d-4a76-b302bbf6944fdd2b dai_lib
b809efaf-5681-42b1-9ed604bb012dd384 dcblock
08aeb4ff-7f68-4c71-86c3c842b4262898 tester
Copy link
Collaborator

Choose a reason for hiding this comment

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

these seem to be alphabetically sorted by the name, please move

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.

5 participants