Message ID | 20250314174800.10142-3-srinivas.kandagatla@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | ASoC: q6apm: fix under runs and fragment sizes | expand |
Hi Srini, On Fri, Mar 14, 2025 at 05:47:57PM +0000, Srinivas Kandagatla wrote: > From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > > Implement an helper function in q6apm to be able to read the current > hardware pointer for both read and write buffers. > > This should help q6apm-dai to get the hardware pointer consistently > without it doing manual calculation, which could go wrong in some race > conditions. > +int q6apm_get_hw_pointer(struct q6apm_graph *graph, int dir) > +{ > + struct audioreach_graph_data *data; > + > + if (dir == SNDRV_PCM_STREAM_PLAYBACK) > + data = &graph->rx_data; > + else > + data = &graph->tx_data; > + > + return (int)atomic_read(&data->hw_ptr); > +} > +EXPORT_SYMBOL_GPL(q6apm_get_hw_pointer); > @@ -553,6 +567,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op) > rd_done = data->payload; > phys = graph->tx_data.buf[hdr->token].phys; > mutex_unlock(&graph->lock); > + /* token numbering starts at 0 */ > + atomic_set(&graph->tx_data.hw_ptr, hdr->token + 1); > > if (upper_32_bits(phys) == rd_done->buf_addr_msw && > lower_32_bits(phys) == rd_done->buf_addr_lsw) { graph->result.opcode = hdr->opcode; graph->result.status = rd_done->status; if (graph->cb) graph->cb(client_event, hdr->token, data->payload, graph->priv); } else { dev_err(dev, "RD BUFF Unexpected addr %08x-%08x\n", rd_done->buf_addr_lsw, rd_done->buf_addr_msw); } I just hit the following error on the T14s with 6.15-rc1 that I've never seen before and which looks like it could be related to this series: q6apm-dai 6800000.remoteproc:glink-edge:gpr:service@1:dais: RD BUFF Unexpected addr ffe0d200-00000001 Any ideas about what may be causing this? Johan
Thanks Johan, On 07/04/2025 12:25, Johan Hovold wrote: > Hi Srini, > > On Fri, Mar 14, 2025 at 05:47:57PM +0000, Srinivas Kandagatla wrote: >> From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> >> >> Implement an helper function in q6apm to be able to read the current >> hardware pointer for both read and write buffers. >> >> This should help q6apm-dai to get the hardware pointer consistently >> without it doing manual calculation, which could go wrong in some race >> conditions. > >> +int q6apm_get_hw_pointer(struct q6apm_graph *graph, int dir) >> +{ >> + struct audioreach_graph_data *data; >> + >> + if (dir == SNDRV_PCM_STREAM_PLAYBACK) >> + data = &graph->rx_data; >> + else >> + data = &graph->tx_data; >> + >> + return (int)atomic_read(&data->hw_ptr); >> +} >> +EXPORT_SYMBOL_GPL(q6apm_get_hw_pointer); > >> @@ -553,6 +567,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op) >> rd_done = data->payload; >> phys = graph->tx_data.buf[hdr->token].phys; >> mutex_unlock(&graph->lock); >> + /* token numbering starts at 0 */ >> + atomic_set(&graph->tx_data.hw_ptr, hdr->token + 1); >> >> if (upper_32_bits(phys) == rd_done->buf_addr_msw && >> lower_32_bits(phys) == rd_done->buf_addr_lsw) { > > graph->result.opcode = hdr->opcode; > graph->result.status = rd_done->status; > if (graph->cb) > graph->cb(client_event, hdr->token, data->payload, graph->priv); > } else { > dev_err(dev, "RD BUFF Unexpected addr %08x-%08x\n", rd_done->buf_addr_lsw, > rd_done->buf_addr_msw); > } > > I just hit the following error on the T14s with 6.15-rc1 that I've never > seen before and which looks like it could be related to this series: Its unlikely, but the timings have changed here. I have not seen it either, but I will try to reproduce this with 6.15-rc1. > > q6apm-dai 6800000.remoteproc:glink-edge:gpr:service@1:dais: RD BUFF Unexpected addr ffe0d200-00000001 > > Any ideas about what may be causing this? How easy is this to reproduce? --srini > > Johan
On Tue, Apr 08, 2025 at 09:07:27AM +0100, Srinivas Kandagatla wrote: > On 07/04/2025 12:25, Johan Hovold wrote: > > On Fri, Mar 14, 2025 at 05:47:57PM +0000, Srinivas Kandagatla wrote: > >> From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > >> > >> Implement an helper function in q6apm to be able to read the current > >> hardware pointer for both read and write buffers. > >> > >> This should help q6apm-dai to get the hardware pointer consistently > >> without it doing manual calculation, which could go wrong in some race > >> conditions. > >> @@ -553,6 +567,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op) > >> rd_done = data->payload; > >> phys = graph->tx_data.buf[hdr->token].phys; > >> mutex_unlock(&graph->lock); > >> + /* token numbering starts at 0 */ > >> + atomic_set(&graph->tx_data.hw_ptr, hdr->token + 1); > >> > >> if (upper_32_bits(phys) == rd_done->buf_addr_msw && > >> lower_32_bits(phys) == rd_done->buf_addr_lsw) { > > > > graph->result.opcode = hdr->opcode; > > graph->result.status = rd_done->status; > > if (graph->cb) > > graph->cb(client_event, hdr->token, data->payload, graph->priv); > > } else { > > dev_err(dev, "RD BUFF Unexpected addr %08x-%08x\n", rd_done->buf_addr_lsw, > > rd_done->buf_addr_msw); > > } > > > > I just hit the following error on the T14s with 6.15-rc1 that I've never > > seen before and which looks like it could be related to this series: > Its unlikely, but the timings have changed here. > I have not seen it either, but I will try to reproduce this with 6.15-rc1. > > > > q6apm-dai 6800000.remoteproc:glink-edge:gpr:service@1:dais: RD BUFF Unexpected addr ffe0d200-00000001 > > > > Any ideas about what may be causing this? > How easy is this to reproduce? I've only noticed this error once on the first boot of 6.15-rc1, and it does not seem to show up again now. I did a fair bit of testing with this series on 6.14-rcs, but did not check the logs while doing so (and there's nothing in the logs I still have). Johan
diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c index 2a2a5bd98110..ca57413cb784 100644 --- a/sound/soc/qcom/qdsp6/q6apm.c +++ b/sound/soc/qcom/qdsp6/q6apm.c @@ -494,6 +494,19 @@ int q6apm_read(struct q6apm_graph *graph) } EXPORT_SYMBOL_GPL(q6apm_read); +int q6apm_get_hw_pointer(struct q6apm_graph *graph, int dir) +{ + struct audioreach_graph_data *data; + + if (dir == SNDRV_PCM_STREAM_PLAYBACK) + data = &graph->rx_data; + else + data = &graph->tx_data; + + return (int)atomic_read(&data->hw_ptr); +} +EXPORT_SYMBOL_GPL(q6apm_get_hw_pointer); + static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op) { struct data_cmd_rsp_rd_sh_mem_ep_data_buffer_done_v2 *rd_done; @@ -520,7 +533,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op) done = data->payload; phys = graph->rx_data.buf[token].phys; mutex_unlock(&graph->lock); - + /* token numbering starts at 0 */ + atomic_set(&graph->rx_data.hw_ptr, token + 1); if (lower_32_bits(phys) == done->buf_addr_lsw && upper_32_bits(phys) == done->buf_addr_msw) { graph->result.opcode = hdr->opcode; @@ -553,6 +567,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op) rd_done = data->payload; phys = graph->tx_data.buf[hdr->token].phys; mutex_unlock(&graph->lock); + /* token numbering starts at 0 */ + atomic_set(&graph->tx_data.hw_ptr, hdr->token + 1); if (upper_32_bits(phys) == rd_done->buf_addr_msw && lower_32_bits(phys) == rd_done->buf_addr_lsw) { diff --git a/sound/soc/qcom/qdsp6/q6apm.h b/sound/soc/qcom/qdsp6/q6apm.h index c248c8d2b1ab..7ce08b401e31 100644 --- a/sound/soc/qcom/qdsp6/q6apm.h +++ b/sound/soc/qcom/qdsp6/q6apm.h @@ -2,6 +2,7 @@ #ifndef __Q6APM_H__ #define __Q6APM_H__ #include <linux/types.h> +#include <linux/atomic.h> #include <linux/slab.h> #include <linux/wait.h> #include <linux/kernel.h> @@ -77,6 +78,7 @@ struct audioreach_graph_data { uint32_t num_periods; uint32_t dsp_buf; uint32_t mem_map_handle; + atomic_t hw_ptr; }; struct audioreach_graph { @@ -150,4 +152,5 @@ int q6apm_enable_compress_module(struct device *dev, struct q6apm_graph *graph, int q6apm_remove_initial_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples); int q6apm_remove_trailing_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples); int q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph, uint32_t codec_id); +int q6apm_get_hw_pointer(struct q6apm_graph *graph, int dir); #endif /* __APM_GRAPH_ */