Skip to content

Commit 15f94f6

Browse files
tmlemankv2019i
authored andcommitted
ipc4: logging: prevent re-initialization on multiple enable calls
Multiple IPC4_ENABLE_LOGS commands can cause FW crashes due to re-initialization of already active resources. This occurs when: - Backend is auto-started at boot and test sends enable command - Test sends multiple enable commands for reconfiguration - Enable is called without checking current state Changes: - Use K_MUTEX_DEFINE() for static mutex initialization instead of runtime k_mutex_init() to prevent re-initialization - Check work queue handler before initializing with k_work_init_delayable() to avoid re-initializing active work queue - Check log_backend_is_active() before calling log_backend_enable() to handle auto-started backend case - Check work queue handler before flushing and clear it after flush - Check backend active state before calling log_backend_disable() This makes the enable/disable operations idempotent and safe to call multiple times, allowing future support for runtime reconfiguration of logging parameters (aging timer, log level, etc.) while preventing crashes from resource re-initialization. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
1 parent 87ff3ba commit 15f94f6

1 file changed

Lines changed: 16 additions & 7 deletions

File tree

src/ipc/ipc4/logging.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static uint32_t mtrace_aging_timer = IPC4_MTRACE_NOTIFY_AGING_TIMER_MS;
6161

6262
#define MTRACE_IPC_CORE PLATFORM_PRIMARY_CORE_ID
6363

64-
static struct k_mutex log_mutex;
64+
static K_MUTEX_DEFINE(log_mutex);
6565
static struct k_work_delayable log_work;
6666

6767
static void mtrace_log_hook_unlocked(size_t written, size_t space_left)
@@ -141,11 +141,13 @@ int ipc4_logging_enable_logs(bool first_block,
141141

142142
if (log_state->enable) {
143143
adsp_mtrace_log_init(mtrace_log_hook);
144+
/* Initialize work queue if not already initialized */
145+
if (!log_work.work.handler)
146+
k_work_init_delayable(&log_work, log_work_handler);
144147

145-
k_mutex_init(&log_mutex);
146-
k_work_init_delayable(&log_work, log_work_handler);
147-
148-
log_backend_enable(log_backend, mtrace_log_hook, CONFIG_SOF_LOG_LEVEL);
148+
/* Enable backend if not already active */
149+
if (!log_backend_is_active(log_backend))
150+
log_backend_enable(log_backend, mtrace_log_hook, CONFIG_SOF_LOG_LEVEL);
149151

150152
mtrace_aging_timer = log_state->aging_timer_period;
151153
if (mtrace_aging_timer < IPC4_MTRACE_AGING_TIMER_MIN_MS) {
@@ -157,9 +159,16 @@ int ipc4_logging_enable_logs(bool first_block,
157159
/* Logs enabled, this is the best place to run boot-tests */
158160
TEST_RUN_ONCE(sof_run_boot_tests);
159161
} else {
160-
k_work_flush_delayable(&log_work, &ipc4_log_work_sync);
162+
/* Flush work queue if initialized */
163+
if (log_work.work.handler) {
164+
k_work_flush_delayable(&log_work, &ipc4_log_work_sync);
165+
log_work.work.handler = NULL;
166+
}
167+
161168
adsp_mtrace_log_init(NULL);
162-
log_backend_disable(log_backend);
169+
/* Disable backend if currently active */
170+
if (log_backend_is_active(log_backend))
171+
log_backend_disable(log_backend);
163172
}
164173

165174
return 0;

0 commit comments

Comments
 (0)