diff options
author | Andreas Pape <apape@de.adit-jv.com> | 2022-09-26 18:58:13 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-10-26 13:19:28 +0200 |
commit | 6a956425411f587f10d9de3cdb388ee62ecfa33a (patch) | |
tree | a71d3a84338f24995dc583c69e5bd65b7ba8f415 /sound | |
parent | 57ff158b9014508be02a369fd2f98f614b13afd2 (diff) | |
download | linux-stable-6a956425411f587f10d9de3cdb388ee62ecfa33a.tar.gz linux-stable-6a956425411f587f10d9de3cdb388ee62ecfa33a.tar.bz2 linux-stable-6a956425411f587f10d9de3cdb388ee62ecfa33a.zip |
ALSA: dmaengine: increment buffer pointer atomically
[ Upstream commit d1c442019594692c64a70a86ad88eb5b6db92216 ]
Setting pointer and afterwards checking for wraparound leads
to the possibility of returning the inconsistent pointer position.
This patch increments buffer pointer atomically to avoid this issue.
Fixes: e7f73a1613567a ("ASoC: Add dmaengine PCM helper functions")
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
Link: https://lore.kernel.org/r/1664211493-11789-1-git-send-email-erosca@de.adit-jv.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/pcm_dmaengine.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index 8eb58c709b14..6f6da1128edc 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -139,12 +139,14 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data); static void dmaengine_pcm_dma_complete(void *arg) { + unsigned int new_pos; struct snd_pcm_substream *substream = arg; struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); - prtd->pos += snd_pcm_lib_period_bytes(substream); - if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream)) - prtd->pos = 0; + new_pos = prtd->pos + snd_pcm_lib_period_bytes(substream); + if (new_pos >= snd_pcm_lib_buffer_bytes(substream)) + new_pos = 0; + prtd->pos = new_pos; snd_pcm_period_elapsed(substream); } |