-
Notifications
You must be signed in to change notification settings - Fork 350
ipc4: ace: Add dynamic log level control via IPC with runtime filtering #10536
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
base: main
Are you sure you want to change the base?
ipc4: ace: Add dynamic log level control via IPC with runtime filtering #10536
Conversation
This commit will be replaced with actual zephyr update after necessary changes are merged. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
Implement dynamic log level selection based on the logs_mask field from the IPC4_ENABLE_LOGS command, allowing the host to control firmware logging verbosity at runtime. Previously, logging was enabled with a fixed compile-time level (CONFIG_SOF_LOG_LEVEL), preventing dynamic control. This change parses the logs_mask[0] bits 0-4 to determine the requested log level and passes it to the backend. Mask bit mapping to Zephyr log levels: - bit 0 (critical/error) -> LOG_LEVEL_ERR (1) - bit 1 (high/warning) -> LOG_LEVEL_WRN (2) - bit 2 (medium) -> LOG_LEVEL_WRN (2) - bit 3 (low/info) -> LOG_LEVEL_INF (3) - bit 4 (verbose/debug) -> LOG_LEVEL_DBG (4) The highest set bit determines the maximum log level. This allows the host to request ERROR-only logging for quiet operation, or DEBUG for verbose troubleshooting, without firmware recompilation. Additionally, log_backend_enable() is now always called (it is idempotent and safe for reconfiguration), removing the previous check that prevented level changes on already-active backends. A TODO comment documents that the mask handling should be improved with proper macros or structs in the future for better code maintainability, but the current implementation is sufficient. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
Enable CONFIG_LOG_RUNTIME_FILTERING and set CONFIG_LOG_RUNTIME_DEFAULT_LEVEL to 1 (ERROR) for all Intel ADSP ACE platforms. This provides quiet firmware boot with minimal logging overhead while maintaining full DEBUG compile-time capability for dynamic log level control via IPC. Platforms configured: - intel_adsp_ace15_mtpm - intel_adsp_ace20_lnl - intel_adsp_ace30_ptl - intel_adsp_ace30_wcl - intel_adsp_ace40_nvl - intel_adsp_ace40_nvls With these settings: - Firmware boots showing only ERROR level logs (quiet startup) - Host can dynamically increase verbosity to INFO or DEBUG via IPC4_ENABLE_LOGS without recompilation - All log macros (LOG_ERR, LOG_INF, etc.) remain compiled in Runtime filtering is explicitly disabled in debug_overlay.conf to maintain current debug build behavior where logs are not filtered at runtime. This works in conjunction with the IPC4 logging handler changes that parse logs_mask to set the appropriate runtime filter level. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
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
Adds IPC4-driven runtime log level control so the host can adjust firmware logging verbosity dynamically, and enables Zephyr runtime log filtering on Intel ADSP ACE boards with a quiet default.
Changes:
- Parse
logs_maskfromIPC4_ENABLE_LOGSand derive a Zephyr log level used when enabling the backend. - Enable
CONFIG_LOG_RUNTIME_FILTERINGand setCONFIG_LOG_RUNTIME_DEFAULT_LEVEL=1(ERROR) across multiple Intel ADSP ACE board configs. - Point the Zephyr west manifest to an upstream PR branch providing
CONFIG_LOG_RUNTIME_DEFAULT_LEVEL.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| west.yml | Switch Zephyr revision to the upstream PR providing CONFIG_LOG_RUNTIME_DEFAULT_LEVEL. |
| src/ipc/ipc4/logging.c | Compute log level from IPC4 logs_mask and pass it to log_backend_enable(). |
| app/debug_overlay.conf | Sets runtime filtering to n in the debug overlay config. |
| app/boards/intel_adsp_ace40_nvls.conf | Enables runtime filtering and sets default runtime level to ERROR. |
| app/boards/intel_adsp_ace40_nvl.conf | Enables runtime filtering and sets default runtime level to ERROR. |
| app/boards/intel_adsp_ace30_wcl.conf | Enables runtime filtering and sets default runtime level to ERROR. |
| app/boards/intel_adsp_ace30_ptl.conf | Enables runtime filtering and sets default runtime level to ERROR. |
| app/boards/intel_adsp_ace20_lnl.conf | Enables runtime filtering and sets default runtime level to ERROR. |
| app/boards/intel_adsp_ace15_mtpm.conf | Enables runtime filtering and sets default runtime level to ERROR. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - name: zephyr | ||
| repo-path: zephyr | ||
| revision: f6a32b27dc17bdb4e1ba4ad84de0c56ca71e257d | ||
| revision: pull/103820/head |
Copilot
AI
Feb 10, 2026
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.
revision: pull/103820/head is unlikely to be fetchable by west/git with the default refspec (GitHub PR refs under refs/pull/... are not typically fetched). This can make west update fail to resolve the revision. Prefer pinning to the PR head commit SHA, or add an explicit fetch/refspec that fetches the PR ref so the revision is guaranteed to exist.
| revision: pull/103820/head | |
| revision: 0123456789abcdef0123456789abcdef01234567 |
| /* Initialize work queue if not already initialized */ | ||
| if (!log_work.work.handler) | ||
| k_work_init_delayable(&log_work, log_work_handler); | ||
|
|
Copilot
AI
Feb 10, 2026
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.
log_backend_enable() is now called unconditionally even if the backend is already active (the previous log_backend_is_active() guard was removed). In Zephyr, enabling an already-enabled backend can be unsafe (e.g., assertions, duplicate registration, or inconsistent state). Reintroduce the active check, and when already active update the runtime filter level using the logging runtime-filter API (or disable+enable explicitly if that's the intended pattern).
| /* Avoid enabling an already active backend; use disable+enable to reconfigure safely */ | |
| if (log_backend_is_active(log_backend)) | |
| log_backend_disable(log_backend); |
| uint32_t log_level = LOG_LEVEL_ERR; /* Default to ERROR if no mask bits set */ | ||
| uint32_t mask = log_state->logs_mask[0]; | ||
|
|
||
| /* TODO: Improve mask handling for better code maintainability |
Copilot
AI
Feb 10, 2026
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 inline comment says the default is ERROR if no mask bits are set, but the logic later sets log_level = LOG_LEVEL_NONE when no bits are set. Please align the comment with the actual behavior (or adjust the behavior to match the comment) to avoid misleading future readers.
| CONFIG_GDBSTUB_ENTER_IMMEDIATELY=n | ||
|
|
||
| # Logging options | ||
| CONFIG_LOG_RUNTIME_FILTERING=n No newline at end of file |
Copilot
AI
Feb 10, 2026
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 overlay explicitly disables runtime filtering, which appears to conflict with the PR’s goal of dynamic log level control via IPC at runtime. If this overlay is used for development/debug builds, consider enabling runtime filtering here (or add a short comment explaining why it must be disabled) to avoid surprising behavior when the overlay is applied.
| CONFIG_LOG_RUNTIME_FILTERING=n | |
| CONFIG_LOG_RUNTIME_FILTERING=y |
| /* Enable backend if not already active */ | ||
| if (!log_backend_is_active(log_backend)) | ||
| log_backend_enable(log_backend, mtrace_log_hook, CONFIG_SOF_LOG_LEVEL); | ||
| log_backend_enable(log_backend, mtrace_log_hook, log_level); |
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.
Does it make sense to enable backend for LOG_LEVEL_NONE?
|
@kv2019i what does Linux support for this IPC look like? Presumably it needs to be implemented? Is it fine to immediately switch the default log filtering state? |
This PR adds support for dynamic firmware log level control through the IPC4_ENABLE_LOGS command, allowing the host to adjust logging verbosity at runtime without firmware recompilation.
Dependencies:
This PR depends on Zephyr upstream PR that adds
CONFIG_LOG_RUNTIME_DEFAULT_LEVEL:Changes Overview:
IPC4 logging handler enhancement - Parse logs_mask field from IPC4_ENABLE_LOGS to determine requested log level and pass it to the backend, enabling dynamic control (ERROR/WARNING/INFO/DEBUG) based on host request
Platform configuration updates - Enable runtime filtering with ERROR default level for all Intel ADSP ACE platforms (MTL/LNL/PTL/WCL/NVL/NVLS), providing quiet boot while maintaining full debug capability