From 4c09f202af0472c7206965968a33faefb65c1ce7 Mon Sep 17 00:00:00 2001 From: Mateusz Junkier Date: Wed, 4 Mar 2026 09:53:36 +0100 Subject: [PATCH] ASoC: SOF: ipc4-mtrace: resync host_read_ptr on debugfs open and release IPC4 mtrace debugfs read handler advances host_read_ptr in SRAM after consuming all available data. When file descriptor is closed, host_read_ptr is left equal to dsp_write_ptr in kernel core_data cache. So subsequent open() inherits this stale pointer. first read() call, sof_wait_mtrace_avail() find host_read_ptr == dsp_write_ptr and block waiting for NOTIFY_LOG_BUFFER_STATUS IPC from fw. Platforms with low post-boot DSP activity timer (256 ms) may not work good with reader timeout window, resulting in empty trace output. Fix this by re-reading dsp_write_ptr directly from SRAM in open() and aligning host_read_ptr to it, so new reader starts from current write position without waiting for IPC notification. Also reset host_read_ptr to dsp_write_ptr in release() to leave core_data to consistent state. Reset target is dsp_write_ptr (not 0) to avoid re-reading stale data that may remain before last wrap of circular buffer. Signed-off-by: Mateusz Junkier --- sound/soc/sof/ipc4-mtrace.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sound/soc/sof/ipc4-mtrace.c b/sound/soc/sof/ipc4-mtrace.c index 667dda3f043978..deea9e3d882439 100644 --- a/sound/soc/sof/ipc4-mtrace.c +++ b/sound/soc/sof/ipc4-mtrace.c @@ -109,6 +109,26 @@ static int sof_ipc4_mtrace_dfs_open(struct inode *inode, struct file *file) return -ENOMEM; } + /* + * Re-sync dsp_write_ptr from SRAM and align host_read_ptr to it so + * this reader starts from current write position and only sees + * data written after this open(). Without this prior reader (e.g. + * one-shot dd) may have advanced host_read_ptr to equal + * dsp_write_ptr, causing next reader to block indefinitely on + * platforms with low DSP activity.Resetting to current dsp_write_ptr + * (not to 0) avoids re-reading stale data from wrapped circular buffer. + */ + if (core_data->slot_offset != SOF_IPC4_INVALID_SLOT_OFFSET) { + struct snd_sof_dev *sdev = core_data->sdev; + u32 write_ptr; + + sof_mailbox_read(sdev, core_data->slot_offset + sizeof(u32), + &write_ptr, sizeof(write_ptr)); + write_ptr -= write_ptr % 4; + core_data->dsp_write_ptr = write_ptr; + core_data->host_read_ptr = write_ptr; + } + ret = simple_open(inode, file); if (ret) { kfree(core_data->log_buffer); @@ -254,6 +274,14 @@ static int sof_ipc4_mtrace_dfs_release(struct inode *inode, struct file *file) scoped_guard(mutex, &core_data->buffer_lock) { kfree(core_data->log_buffer); core_data->log_buffer = NULL; + /* + * Align host_read_ptr to current dsp_write_ptr so that + * subsequent open() starts from fresh data and isnt + * blocked by stale pointer left by this reader. Using + * dsp_write_ptr (not 0) avoids re-reading stale data from + * wrapped circular buffer. + */ + core_data->host_read_ptr = core_data->dsp_write_ptr; } return 0;