Skip to content

trace: Adaptive rate-limiting of repetitive messages - #3456

Merged
lgirdwood merged 6 commits into
thesofproject:masterfrom
akloniex:trace-suppress
Nov 27, 2020
Merged

trace: Adaptive rate-limiting of repetitive messages#3456
lgirdwood merged 6 commits into
thesofproject:masterfrom
akloniex:trace-suppress

Conversation

@akloniex

Copy link
Copy Markdown
Member

As discussed recently here: #3362, here's my take on the trace rate-limiting subject.

Many of the options are configurable via Kconfig options, which should allow developers to fine tune, or turn off the feature if they have the need to do so.

The main idea is to track few last messages, and if they're sent again during defined time period, suppress those messages, and count such events. After leaving the filter memory, information about the suppressed message is emitted.

During the review, I suggest reading the Kconfig help messages first, to get a better view how these options mesh with one another.

@dbaluta

dbaluta commented Sep 23, 2020

Copy link
Copy Markdown
Collaborator

Does anyone know how the Linux kernel handles ratelimiting? Not sure if need to reinvent the wheel.

@marc-hb

marc-hb commented Sep 24, 2020

Copy link
Copy Markdown
Collaborator

The main idea is to track few last messages, and if they're sent again during defined time period, suppress those messages, and count such events. After leaving the filter memory, information about the suppressed message is emitted.

This seems different from the Linux kernel which apparently doesn't remember anything about suppressed messages and requires invoking a special printk_ratelimited(message) function.

It looks more similar to "repeat reduction" in userspace syslogger like https://www.rsyslog.com/doc/master/configuration/action/rsconf1_repeatedmsgreduction.html

@akloniex

Copy link
Copy Markdown
Member Author

@dbaluta @marc-hb That is correct, this implementation is different from one in kernel. Please refer to discussion in #3362

@akloniex
akloniex force-pushed the trace-suppress branch 2 times, most recently from a79b639 to 73c3de1 Compare September 24, 2020 08:26
Comment thread src/trace/trace.c Outdated
Comment on lines 112 to 114

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.

I thought about changing id_1 and id_2 to pipe_id and comp_id, I didn't do that yet, but maybe it's good PR for that, because those names are duplicated a few times here.

@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.

Just minor questions - one thing that does come up is that any user supplied trace filtering should disable the rate limiting at runtime (since the user is actively controlling trace). We need to make sure this will align.

Comment thread src/trace/Kconfig Outdated
Comment thread src/trace/Kconfig Outdated
Comment thread src/trace/trace.c Outdated
@mwasko

mwasko commented Sep 29, 2020

Copy link
Copy Markdown
Contributor

Does anyone know how the Linux kernel handles ratelimiting? Not sure if need to reinvent the wheel.

@dbaluta the proposed solution is more developer friendly then Linux kernel approach. Please check PR3362 for details and discussion comparing both approaches.

@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.

Does this now have the extra flag to disable when the user starts manually creating trace filters ?

Comment thread src/trace/trace.c Outdated
@akloniex

Copy link
Copy Markdown
Member Author

@lgirdwood Flag to disable adaptive trace filtering/rate-limiting added in separate commit.

@akloniex

akloniex commented Oct 1, 2020

Copy link
Copy Markdown
Member Author

SOFCI TEST

Comment thread src/trace/trace.c Outdated

@lyakh lyakh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

let's simplify kconfig and re-review, it's too confusing now and needlessly complex to test

Comment thread src/trace/trace.c Outdated
Comment thread test/cmocka/src/common_mocks.c Outdated
Comment thread src/include/sof/trace/trace.h Outdated
Comment thread src/trace/Kconfig Outdated
Comment thread src/trace/Kconfig Outdated
Comment thread src/trace/trace.c Outdated
Comment thread src/trace/trace.c Outdated
Comment thread src/trace/trace.c Outdated
Comment thread src/trace/trace.c Outdated
Comment thread src/trace/trace.c Outdated
@akloniex
akloniex force-pushed the trace-suppress branch 2 times, most recently from cd9000f to 6058787 Compare October 2, 2020 10:27
@akloniex

Copy link
Copy Markdown
Member Author

@lyakh there is burst support. Added in last commit.

Comment thread src/trace/trace.c Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this defeats the purpose of platform_shared_commit() above

Comment thread src/trace/trace.c Outdated
@lyakh

lyakh commented Nov 16, 2020

Copy link
Copy Markdown
Collaborator

@lyakh there is burst support. Added in last commit.

@akloniex right, sorry, missed it. I commented on it too, and other comments to the rest of this PR remain

@lgirdwood

Copy link
Copy Markdown
Member

CI is showing unrelated issue on APL.
@lyakh are all your questions resolved now ?
@akloniex btw - it looks like we are suppressing useful messages e.g. the comp performance counters

[    59359.791667] (      826.875000) c0 dai          4.26      src/audio/pipeline.c:206  perf comp_copy peak plat 158 cpu 2654
[    59383.489583] (       23.697916) c0 pga          4.23      src/audio/pipeline.c:206  perf comp_copy peak plat 327 cpu 5444
[    59398.385417] (       14.895833) c0 host         4.22      src/audio/pipeline.c:206  perf comp_copy peak plat 160 cpu 2666
[    59414.166667] (       15.781250) c0 dai          12.50     src/audio/pipeline.c:206  perf comp_copy peak plat 149 cpu 2506
[    59454.062500] (       39.895832) c0 ll-schedule        ./schedule/ll_schedule.c:202  perf ll_work peak plat 3828 cpu 63756
[    60375.156250] (      921.093750) c0 dma-trace                 src/trace/trace.c:142  Suppressed 2 similar messages: perf comp_copy peak plat %d cpu %d
[    60380.312500] (        5.156250) c0 pga          4.23      src/audio/pipeline.c:206  perf comp_copy peak plat 335 cpu 5582
[    60394.843750] (       14.531250) c0 host         4.22      src/audio/pipeline.c:206  perf comp_copy peak plat 163 cpu 2738
[    60411.406250] (       16.562500) c0 dai          12.50     src/audio/pipeline.c:206  perf comp_copy peak plat 167 cpu 2778
[    60435.208333] (       23.802084) c0 pga          12.47     src/audio/pipeline.c:206  perf comp_copy peak plat 337 cpu 5612
[    60456.302083] (       21.093750) c0 ll-schedule        ./schedule/ll_schedule.c:202  perf ll_work peak plat 3868 cpu 64436
[    61316.458333] (      860.156250) c0 dma-trace                 src/trace/trace.c:142  Suppressed 1 similar messages: perf comp_copy peak plat %d cpu %d

@lyakh lyakh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

looks much better now, thanks for the improvements! Just a couple more comments and we probably have to decide on a printing format specifier.

Comment thread src/trace/trace.c
spinlock_t lock; /* locking mechanism */

#if CONFIG_TRACE_FILTERING_ADAPTIVE
struct recent_trace_context trace_core_context[CONFIG_CORE_COUNT];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

is this enough for multicore? Cores while printing will cache this data. They'll modify their respective entries, according to their core ID, then if they need to they'll write those cache lines back. But if those cache lines cross borders of array elements, won't they corrupt data for adjacent cores? Don't we need to cache-line align these elements? In fact the trace data is allocated from SOF_MEM_ZONE_SYS_SHARED so that shouldn't be a problem but I have to clarify my doubts about whether locking is required together with platform_shared_commit()

Comment thread src/trace/trace.c
Comment thread src/trace/trace.c Outdated
Comment thread src/trace/trace.c Outdated
static void emit_recent_entry(struct recent_log_entry *entry)
{
_log_message(trace_log_unfiltered, false, LOG_LEVEL_INFO, _TRACE_INV_CLASS, &dt_tr,
_TRACE_INV_ID, _TRACE_INV_ID, "Suppressed %u similar messages: %pE",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is interesting. Has this been decided? This is a new format, with it you'll get something like

Suppressed 2 similar messages: perf comp_copy peak plat %d cpu %d

I think we're trying to comply with the standard for printing formats. If not with POSIX then at least with the kernel. In the kernel "%pE" is used for "printing raw buffer as an escaped string." This isn't the same as that, right? But I also don't see a suitable format, so, I'm not sure what a good choice here be. We also could in principle consider printing messages like

Suppressed 2 similar messages: function _rfree_unlocked() line 925

or "file alloc.c line 925." Not sure either of these options is better, but at least we could have standard format strings for them. E.g. if we use function + line number, we could use some form of a %ps / %pS format. @lgirdwood ?

@akloniex
akloniex force-pushed the trace-suppress branch 2 times, most recently from eddc3d1 to 848c7ca Compare November 19, 2020 13:01
@lgirdwood

Copy link
Copy Markdown
Member

looks much better now, thanks for the improvements! Just a couple more comments and we probably have to decide on a printing format specifier.

printing format specifiers should be POSIX compliant and exactly the same as Zephyr. @dcpleung fyi

@lgirdwood

Copy link
Copy Markdown
Member

looks much better now, thanks for the improvements! Just a couple more comments and we probably have to decide on a printing format specifier.

printing format specifiers should be POSIX compliant and exactly the same as Zephyr. @dcpleung fyi

@akloniex can you confirm we are using POSIX compliant print specifiers ?

@akloniex

Copy link
Copy Markdown
Member Author

looks much better now, thanks for the improvements! Just a couple more comments and we probably have to decide on a printing format specifier.

printing format specifiers should be POSIX compliant and exactly the same as Zephyr. @dcpleung fyi

@akloniex can you confirm we are using POSIX compliant print specifiers ?

@lgirdwood we're using %pE. IIUC %p specifiers are used for printing/retrieving data via pointer, and following specifiers denote how the data should be interpreted, but I haven't found any standardized table of such specifiers. These might be implementation-dependent, or not documented very well. If you know where to find such details, I'll verify that this specifier complies with the rules.

@lgirdwood

Copy link
Copy Markdown
Member

@akloniex I think we are aligned with https://en.wikipedia.org/wiki/Printf_format_string but can you check to be sure.
@lyakh I assume now the trace print formatting is aligned with Zephyr too (since Zephyr log is aligned with C library) ?

@lyakh

lyakh commented Nov 25, 2020

Copy link
Copy Markdown
Collaborator

@lyakh I assume now the trace print formatting is aligned with Zephyr too (since Zephyr log is aligned with C library) ?

@lgirdwood I don't see any print format changes in this version compared to the previous one. As @akloniex mentioned, %pE isn't a part of any standard, and it isn't used in Zephyr, but it is used in the kernel https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/core-api/printk-formats.rst?h=v5.10-rc5#n210 and that use is incompatible with this proposed use.

@akloniex

Copy link
Copy Markdown
Member Author

@lyakh I assume now the trace print formatting is aligned with Zephyr too (since Zephyr log is aligned with C library) ?

@lgirdwood I don't see any print format changes in this version compared to the previous one. As @akloniex mentioned, %pE isn't a part of any standard, and it isn't used in Zephyr, but it is used in the kernel https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/core-api/printk-formats.rst?h=v5.10-rc5#n210 and that use is incompatible with this proposed use.

@lyakh Thanks for the resource.
@lgirdwood As mentioned, %pE specifier is already occupied in kernel, and does not match our needs. Should we come up with a specifier that is not used yet? I don't see any other reasonable option here.

@lyakh

lyakh commented Nov 25, 2020

Copy link
Copy Markdown
Collaborator

@lgirdwood As mentioned, %pE specifier is already occupied in kernel, and does not match our needs. Should we come up with a specifier that is not used yet? I don't see any other reasonable option here.

@akloniex if we insist on printing the format string, then yes, this doesn't exist in the kernel, so, we'd need our own format. However, as I proposed above, we could instead print a function name and an "offset." If we print it like in backtraces with an address offset, that would be compatible with the kernel but not very user-friendly and it would use %ps or %pS. If we want a more user-friendly version, we could print a line number as the "offset," but I'm not sure whether we'd then still want to use %ps or %pS or invent our own suffix.

@akloniex

Copy link
Copy Markdown
Member Author

@lyakh We cannot print function name, as it's not available in ldc file, because we cannot use any variant of __func__ macro, since it's not sufficiently compile-time constant for the compiler to put that into defined code section.

@lgirdwood

Copy link
Copy Markdown
Member

@lgirdwood As mentioned, %pE specifier is already occupied in kernel, and does not match our needs. Should we come up with a specifier that is not used yet? I don't see any other reasonable option here.

Yes, lets use something different in our case. We should not change the meaning of any used by the kernel (since it's a defacto standard).

This separates trace filtering from actual sending of the message
and allows usage of sending function without filtering, when necessary.

Signed-off-by: Artur Kloniecki <arturx.kloniecki@linux.intel.com>
Also create trace_log_unfiltered() function, to be used internally
by tracing subsystem to emit information about suppressed trace messages.

The *unfiltered function could be also used as replacement
in _log_message() macro, to disable log filtering for debugging purposes.

Signed-off-by: Artur Kloniecki <arturx.kloniecki@linux.intel.com>
Few recent messages are remembered by the filter, and repetitive messages
reported in short period of time are suppressed. Solution is compile-time
configurable via many Kconfig options, as documented in Kconfig.

Signed-off-by: Artur Kloniecki <arturx.kloniecki@linux.intel.com>
When user manually overrides trace filtering settings, adaptive trace
rate-limiting is disabled. This assures, that when user deliberately
changes filters, all trace messages are being delivered.

Signed-off-by: Artur Kloniecki <arturx.kloniecki@linux.intel.com>
To allow proper display of suppressed message info traces, %pQ specifier
was chosen to decode pointers to log entries.
Helper function asprintf_entry_text() is used to handle the log entry
text for display.

Signed-off-by: Artur Kloniecki <arturx.kloniecki@linux.intel.com>
Introduce TRACE_BURST_COUNT Kconfig setting, which allows to define amount
of messages that are allowed to pass through the filter before suppression
kicks in.

Signed-off-by: Artur Kloniecki <arturx.kloniecki@linux.intel.com>
@akloniex

Copy link
Copy Markdown
Member Author

@lgirdwood @lyakh Changed specifier to an unused one - %pQ

@lyakh

lyakh commented Nov 27, 2020

Copy link
Copy Markdown
Collaborator

@lgirdwood @lyakh Changed specifier to an unused one - %pQ

thanks! I can go with this. However ideally I'd maybe even try to add this to the aforementioned document in the Linux kernel to make sure they don't use it for something different later. And we still have an option of using something like FILE + LINE. I'm fine whichever way @lgirdwood decides to go from here.

@lyakh lyakh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for all the improvements!

@lgirdwood

Copy link
Copy Markdown
Member

Jenkins shows non booting CML DUT

@lgirdwood
lgirdwood merged commit 4d4a9d7 into thesofproject:master Nov 27, 2020
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.

8 participants