From 4b9d08cee9efefde16fcc7f8115fecd9e94c8e9b Mon Sep 17 00:00:00 2001 From: Mateusz Junkier Date: Wed, 4 Mar 2026 09:53:36 +0100 Subject: [PATCH 1/2] ASoC: SOF: ipc4-mtrace: resync host_read_ptr on debugfs open core_data->dsp_write_ptr is updated on each aging timer IPC, but there is 256ms window between DSP write and IPC. If reader opens in this window and DSP goes idle before next IPC,there wont be further writes and sof_wait_mtrace_avail() blocks until timeout. Fix by reading dsp_write_ptr directly from SRAM in open() to get current write position without waiting for the next IPC. host_read_ptr is left unchanged to preserve inter-session data. Signed-off-by: Mateusz Junkier --- sound/soc/sof/ipc4-mtrace.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/sof/ipc4-mtrace.c b/sound/soc/sof/ipc4-mtrace.c index 667dda3f043978..fa8de5e64644d8 100644 --- a/sound/soc/sof/ipc4-mtrace.c +++ b/sound/soc/sof/ipc4-mtrace.c @@ -109,6 +109,20 @@ static int sof_ipc4_mtrace_dfs_open(struct inode *inode, struct file *file) return -ENOMEM; } + /* + * Re-sync dsp_write_ptr from SRAM on open to avoid blocking when + * DSP goes idle before next aging timer IPC arrives. + */ + 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; + } + ret = simple_open(inode, file); if (ret) { kfree(core_data->log_buffer); From 8250deeffb748cadb0a15a93b10a854c52469281 Mon Sep 17 00:00:00 2001 From: Mateusz Junkier Date: Thu, 12 Mar 2026 09:31:15 +0100 Subject: [PATCH 2/2] Add debug for slot pointer drift detection Signed-off-by: Mateusz Junkier --- sound/soc/sof/ipc4-mtrace.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/sof/ipc4-mtrace.c b/sound/soc/sof/ipc4-mtrace.c index fa8de5e64644d8..9fee5da4047fe7 100644 --- a/sound/soc/sof/ipc4-mtrace.c +++ b/sound/soc/sof/ipc4-mtrace.c @@ -162,6 +162,7 @@ static ssize_t sof_ipc4_mtrace_dfs_read(struct file *file, char __user *buffer, { struct sof_mtrace_core_data *core_data = file->private_data; u32 log_buffer_offset, log_buffer_size, read_ptr, write_ptr; + u32 slot_read_ptr, slot_write_ptr; struct snd_sof_dev *sdev = core_data->sdev; struct sof_mtrace_priv *priv = sdev->fw_trace_data; void *log_buffer = core_data->log_buffer; @@ -188,6 +189,19 @@ static ssize_t sof_ipc4_mtrace_dfs_read(struct file *file, char __user *buffer, if (core_data->slot_offset == SOF_IPC4_INVALID_SLOT_OFFSET) return 0; + /* Compare cached pointers against slot state to catch missed updates. */ + sof_mailbox_read(sdev, core_data->slot_offset, &slot_read_ptr, + sizeof(slot_read_ptr)); + sof_mailbox_read(sdev, core_data->slot_offset + sizeof(u32), &slot_write_ptr, + sizeof(slot_write_ptr)); + slot_write_ptr -= slot_write_ptr % 4; + if (slot_read_ptr != core_data->host_read_ptr || + slot_write_ptr != core_data->dsp_write_ptr) + dev_dbg(sdev->dev, + "core%d ptr mismatch: slot r/w %#x/%#x vs cached r/w %#x/%#x\n", + core_data->id, slot_read_ptr, slot_write_ptr, + core_data->host_read_ptr, core_data->dsp_write_ptr); + /* The log data buffer starts after the two pointer in the slot */ log_buffer_offset = core_data->slot_offset + (sizeof(u32) * 2); /* The log data size excludes the pointers */