-
Notifications
You must be signed in to change notification settings - Fork 349
Probe log autostart and prebuffering #10096
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces automatic activation of probe logging when the probe DMA starts and implements a pre-buffering mechanism to capture early log data before the logging hook is registered. Additionally, it refactors the logging hook signature and fixes typos in the debug_stream module.
- Auto-enables probe logging during
probe_initvia a newprobe_auto_enable_logshelper. - Changes
probe_logging_hookto return processed byte count and adds pre-buffering/draining logic inlog_backend_probe. - Adds a Kconfig option for auto-enable and corrects module name/log formatting in
debug_stream_slot.
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/probe/probe.c | Added probe_auto_enable_logs declaration and invocation; updated probe_logging_hook to return byte count. |
| src/logging/log_backend_probe.c | Introduced log_push, pre-buffer logic (pre_buffer/pre_buffer_drain), and conditional hook invocation. |
| src/logging/Kconfig | Added LOG_BACKEND_SOF_PROBE_OUTPUT_AUTO_ENABLE option. |
| src/include/sof/probe/probe.h | Updated probe_logging_hook_t typedef to return int. |
| src/debug/debug_stream/debug_stream_slot.c | Fixed typos in LOG_MODULE_REGISTER and removed redundant newlines in logging calls. |
Comments suppressed due to low confidence (2)
src/probe/probe.c:341
- [nitpick] Consider adding a brief comment describing when and why
probe_auto_enable_logsshould be used, to improve code readability and maintainability.
static void probe_auto_enable_logs(uint32_t stream_tag);
src/logging/log_backend_probe.c:88
- The new pre-buffering logic is not covered by existing tests; consider adding unit tests to verify behavior when buffering data and when buffer overflows.
static void pre_buffer(uint8_t *data, size_t length)
3a6096c to
a1af44c
Compare
src/probe/probe.c
Outdated
|
|
||
| #if CONFIG_LOG_BACKEND_SOF_PROBE | ||
| static void probe_logging_hook(uint8_t *buffer, size_t length) | ||
| static int probe_logging_hook(uint8_t *buffer, size_t length) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probe_char_out() in log_backend_probe.c be modified as well (and before)? It seems it doesn't handle the case where hook cannot consume all the data currently.
EDIT: ok, the next patch in series changes the logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return ssize_t?
a1af44c to
7904f99
Compare
7904f99 to
1cecf5d
Compare
|
Fixed the check patch issues (typo in commit message, and space after cast), and added a comment to memcpy_s() call about how how it prevents buffer overflows. |
The src/logging/Kconfig has never been rsourced from src/Kconfig, so better to remove the idle file to avoid confusion. The same options are duplicated in src/trace/Kconfig. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
1cecf5d to
189981b
Compare
|
It makes more sense to initialize the probe data right after the allocation than at the end of the function. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
The add config option to automatically enable probes logging when probes extraction dma is started. Signed-off-by: Jyri Sarha <jyri.sarha@intel.com>
189981b to
1dcdad3
Compare
|
src/probe/probe.c
Outdated
| static int probe_logging_hook(uint8_t *buffer, size_t length) | ||
| { | ||
| struct probe_pdata *_probe = probe_get(); | ||
| uint32_t max_len; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
size_t?
src/probe/probe.c
Outdated
|
|
||
| #if CONFIG_LOG_BACKEND_SOF_PROBE | ||
| static void probe_logging_hook(uint8_t *buffer, size_t length) | ||
| static int probe_logging_hook(uint8_t *buffer, size_t length) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return ssize_t?
src/logging/log_backend_probe.c
Outdated
|
|
||
| static void log_push(uint8_t *data, size_t length) | ||
| { | ||
| int pos = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
size_t
src/logging/log_backend_probe.c
Outdated
| static struct probe_pre_buffer { | ||
| uint8_t *buf; | ||
| uint32_t wpos; | ||
| uint32_t len; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't see a need for fixed-size types. I'd use "logical" types like size_t etc.
src/logging/log_backend_probe.c
Outdated
|
|
||
| mlen = snprintf(msg, sizeof(msg), "[Drain %u bytes of pre buffered logs]\n", prebuf.wpos); | ||
| if (prebuf.len > prebuf.wpos) | ||
| mlen += snprintf(&msg[mlen], sizeof(msg) - mlen, "[%u bytes dropped]\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here msg + mlen seems more logical to me than &msg[mlen]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll change that, but these are really a matter of taste.
src/logging/log_backend_probe.c
Outdated
| char msg[80]; | ||
| int mlen; | ||
|
|
||
| mlen = snprintf(msg, sizeof(msg), "[Drain %u bytes of pre buffered logs]\n", prebuf.wpos); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mlen can be > sizeof(msg):
If the output was truncated due to this limit, then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thanks. Forgot about that.
| if (probe_hook) | ||
| probe_hook(data, length); | ||
| if (!probe_hook) { | ||
| pre_buffer(data, length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand the flow, but the buffer is only allocated here, and freed in the first pre_buffer_drain(). How does this work? Are there always calls to probe_char_out() with probe_hook == NULL before a single call to probe_char_out() with probe_hook != NULL?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probe_char_out() is called when ever sometihng is logged. probe_hook is set when probes dma is up and special "log"-probepoint is added (the autoenable option is set its added automatically when probes dma is set up). So the logs are buffered if there is no place to push them and the buffer is drained when the probes dma is started.
.... but hmm, it does not appear the logging hook is disabled any where. That is unfortunate as the buffering is not enabled again even if the probes DMA is dropped. I think there is still need for one more commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsarha ah, thanks for explaining! Somehow didn't catch that yesterday
a7825b3 to
f48c5e2
Compare
lyakh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor comments, can also be addressed in a follow-up
src/probe/probe.c
Outdated
| int ret; | ||
|
|
||
| max_len = _probe->ext_dma.dmapb.avail - sizeof(struct probe_data_packet) - sizeof(checksum); | ||
| length = MIN(max_len, (uint32_t)length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the type-cast doesn't seem to be needed
| buf_id->full_id == buffer_id[i]) { | ||
| #if CONFIG_LOG_BACKEND_SOF_PROBE | ||
| if (enable_logs(&_probe->probe_points[j])) | ||
| probe_logging_init(NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the commit message by "probes module is unloaded" you mean the Linux kernel module? And after this call probes would return to pre-buffering? Sounds good
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, and that indeed happens. I tested that. Here is how it looks like if PROBE_LOG_DEBUG is set:
[ 0.021313] <inf> clock: clock_set_freq: clock 2 set freq 393216000Hz freq_idx 1 old 0
[ 0.021313] <inf> ll_schedule: zephyr_ll_task_schedule_common: task add 0xa01233c0 0xa00bee84U priority 0 flags 0x0
[ 0.021313] <inf> ll_schedule: zephyr_domain_register: zephyr_domain_register domain->type 1 domain->clk 0 domain->ticks_per_ms 38400 period 1000
[ 0.021313] <inf> dai_intel_ssp: dai_ssp_get_properties: SSP32: fifo 172048, handshake 6, init delay 0
^C
root@9049fa09b4de:~# crecord -c3 -d0 -b8192 -f4 -FS32_LE -R48000 -C4 | sof-probes -l
sof-probes: Creating file buffer_16777216.bin
[Drain 881 bytes of pre buffered logs]
[ 0.021606] <inf> ipc: ipc_cmd: rx : 0x4300000d|0x20301000
[ 0.021606] <inf> probe: probe_get_config: comp:255 0xd 1 probe points sent
[ 0.021606] <inf> ipc: ipc_cmd: rx : 0x4400000d|0x30400004
[ 0.021606] <inf> probe: probe_set_config: comp:255 0xd probe_set_config()
[ 0.021606] <inf> ipc: ipc_cmd: rx : 0x4b00000d|0xff0000
[ 0.021606] <inf> probe: probe_free: comp:255 0xd probe_free()
[ 0.021606] <inf> ll_schedule: zephyr_ll_task_done: task complete 0xa0121d28 0xa00bef44U
[ 0.021606] <inf> ll_schedule: zephyr_ll_task_done: num_tasks 1 total_num_tasks 5
[ 0.021606] <inf> ll_schedule: zephyr_domain_unregister: zephyr_domain_unregister domain->type 1 domain->clk 0
[ 0.021606] <inf> dma: sof_dma_put: dma_put(), dma = 0x400cd910, sref = 1
[ 0.021953] <inf> ll_schedule: stats_report: ll core 2 timer avg 5788, max 6200, overruns 0
[Buffer drained in 26 us]
[ 0.022366] <inf> ipc: ipc_cmd: rx : 0x4000000d|0xff000c
[ 0.022366] <inf> probe: probe_mod_init: comp:255 0xd probe_mod_init()
[ 0.022366] <inf> dma: sof_dma_get: dma_get() ID 0 sref = 2 busy channels 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsarha looks good! But is the module there really unloaded or is it just the capture stopped?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lyakh , at least probe_free() and probe_mod_init() is called according to the logs, so AFAICT the module has been unloaded and loaded again.
|
|
||
| mlen = snprintf(msg, sizeof(msg), "[Drain %zu bytes of pre buffered logs]\n", prebuf.wpos); | ||
| if (prebuf.len > prebuf.wpos) | ||
| mlen += snprintf(msg + mlen, sizeof(msg) - mlen, "[%zu bytes dropped]\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this also implicitly assumes that sizeof(msg) < mlen at this point. This should be true with an 80-character msg buffer, but...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I'll add "&& mlen < sizeof(msg)" to the if statement. It would be better if snprintf size argument would be signed so that negative size would be detected.
| if (probe_hook) | ||
| probe_hook(data, length); | ||
| if (!probe_hook) { | ||
| pre_buffer(data, length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsarha ah, thanks for explaining! Somehow didn't catch that yesterday
Write only the amount of bytes that fits to DMA buffer and return the amount written. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
Allocate a 4kb buffer to collect the logs arriving before probes DMA is up. Send the contents of the buffer when the callback indicating that DMA is running is set and free the buffer. Busy wait the DMA progress in case the buffer does not fit into the DMA buffer at once. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
Remove logging hook when logging is disabled or probes module is unloaded. This should re-enable buffering in case the probes dma client crashes and is respawned or something similar happens. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
f48c5e2 to
57df568
Compare
The PR adds probe logging autostart right after the probes DMA is up and pre buffering to collect the logs from before that happens.
The debug_stream PR is there only to fix the typos and extra newlines that got annoying after seeing them too many times.