From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757337AbcHWJSV (ORCPT ); Tue, 23 Aug 2016 05:18:21 -0400 Received: from mail-pf0-f169.google.com ([209.85.192.169]:33823 "EHLO mail-pf0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756725AbcHWJR7 (ORCPT ); Tue, 23 Aug 2016 05:17:59 -0400 From: Hsin-Yu Chao Cc: smbarber@chromium.org, groeck@chromium.org, Hsin-Yu Chao , Vinod Koul , Dan Williams , dmaengine@vger.kernel.org (open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM), linux-kernel@vger.kernel.org (open list) Subject: [PATCH] dmaengine: pl330: Acquire dmac's spinlock in pl330_tx_status Date: Tue, 23 Aug 2016 17:16:55 +0800 Message-Id: <1471943815-30977-1-git-send-email-hychao@chromium.org> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 To: unlisted-recipients:; (no To-header on input) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org There is a racing when accessing dmac thread in pl330_tx_status that the pl330_update is handling active request at the same time and changing the status of descriptors. This could cause an invalid transferred count from BUSY descriptor added up to the residual number. Fix the bug by using the dmac's spinlock in pl330_tx_status to protect thread resources from changing. Note that the nested order of holding dmac's and dma_chan's spinlock is consistent with the rest of the driver: dma_chan first and then dmac, so it is safe from deadlock scenario. Signed-off-by: Hsin-Yu Chao --- drivers/dma/pl330.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 2449cb7..bd6861b 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2306,6 +2306,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, goto out; spin_lock_irqsave(&pch->lock, flags); + spin_lock(&pch->thread->dmac->lock); if (pch->thread->req_running != -1) running = pch->thread->req[pch->thread->req_running].desc; @@ -2348,6 +2349,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, if (desc->last) residual = 0; } + spin_unlock(&pch->thread->dmac->lock); spin_unlock_irqrestore(&pch->lock, flags); out: -- 2.8.0.rc3.226.g39d4020