From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758696AbcLAFYX (ORCPT ); Thu, 1 Dec 2016 00:24:23 -0500 Received: from relay1.mentorg.com ([192.94.38.131]:60951 "EHLO relay1.mentorg.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754355AbcLAFYW (ORCPT ); Thu, 1 Dec 2016 00:24:22 -0500 From: Jiada Wang To: , , CC: , , , Subject: [PATCH v2 1/1] ALSA: SOC: DMA: access buffer pointer atomically Date: Thu, 1 Dec 2016 14:24:22 +0900 Message-ID: <20161201052422.18775-1-jiada_wang@mentor.com> X-Mailer: git-send-email 2.9.3 MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Andreas Pape Setting pointer and afterwards check for wrap around leads to the possibility of returning the inconsistent pointer position. This patch accesses buffer pointer atomically to avoid this issue. v2: use READ_ONCE and WRITE_ONCE to ensure read/write of buffer pointer in only one access also updates snd_dmaengine_pcm_pointer_no_residue to ensure atomic access Signed-off-by: Andreas Pape Signed-off-by: Jiada Wang --- sound/core/pcm_dmaengine.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index 8eb58c7..b6255fd 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; + WRITE_ONCE(prtd->pos, new_pos); snd_pcm_period_elapsed(substream); } @@ -235,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger); snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream) { struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); - return bytes_to_frames(substream->runtime, prtd->pos); + return bytes_to_frames(substream->runtime, READ_ONCE(prtd->pos)); } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer_no_residue); -- 2.9.3