From patchwork Wed Jul 30 08:30:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 4646531 X-Patchwork-Delegate: vinod.koul@intel.com Return-Path: X-Original-To: patchwork-dmaengine@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C70F49F36A for ; Wed, 30 Jul 2014 08:36:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 04A512012B for ; Wed, 30 Jul 2014 08:36:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 21CBF20123 for ; Wed, 30 Jul 2014 08:36:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751596AbaG3Ifz (ORCPT ); Wed, 30 Jul 2014 04:35:55 -0400 Received: from top.free-electrons.com ([176.31.233.9]:53536 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751535AbaG3IfH (ORCPT ); Wed, 30 Jul 2014 04:35:07 -0400 Received: by mail.free-electrons.com (Postfix, from userid 106) id AC45EFDD; Wed, 30 Jul 2014 10:35:06 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost (col31-4-88-188-83-94.fbx.proxad.net [88.188.83.94]) by mail.free-electrons.com (Postfix) with ESMTPSA id 2AC2283C; Wed, 30 Jul 2014 10:35:06 +0200 (CEST) From: Maxime Ripard To: Dan Williams , Vinod Koul Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, dmaengine@vger.kernel.org, Maxime Ripard Subject: [PATCH 3/3] dmaengine: sun6i: Fix memory leaks Date: Wed, 30 Jul 2014 10:30:23 +0200 Message-Id: <1406709023-7650-4-git-send-email-maxime.ripard@free-electrons.com> X-Mailer: git-send-email 2.0.2 In-Reply-To: <1406709023-7650-1-git-send-email-maxime.ripard@free-electrons.com> References: <1406709023-7650-1-git-send-email-maxime.ripard@free-electrons.com> Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The sun6i_dma_prep_memcpy and sun6i_dma_prep_slave_sg functions were both leaking the descriptor they allocated if an error was happening after a successful dma_pool_alloc call. It also fixes a memleak that was happening in the scatter gather list traversal, that was allocating as much descriptor as there was scatter gather items, but only freeing the current descriptor if an error was to arise. Reported-by: Dan Carpenter Signed-off-by: Maxime Ripard --- drivers/dma/sun6i-dma.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c index 63a1db38894e..1f92a56fd2b6 100644 --- a/drivers/dma/sun6i-dma.c +++ b/drivers/dma/sun6i-dma.c @@ -562,8 +562,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli); if (!v_lli) { dev_err(sdev->slave.dev, "Failed to alloc lli memory\n"); - kfree(txd); - return NULL; + goto err_txd_free; } ret = sun6i_dma_cfg_lli(v_lli, src, dest, len, sconfig); @@ -583,6 +582,8 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( err_dma_free: dma_pool_free(sdev->pool, v_lli, p_lli); +err_txd_free: + kfree(txd); return NULL; } @@ -614,17 +615,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( for_each_sg(sgl, sg, sg_len, i) { v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli); - if (!v_lli) { - kfree(txd); - return NULL; - } + if (!v_lli) + goto err_lli_free; if (dir == DMA_MEM_TO_DEV) { ret = sun6i_dma_cfg_lli(v_lli, sg_dma_address(sg), sconfig->dst_addr, sg_dma_len(sg), sconfig); if (ret) - goto err_dma_free; + goto err_cur_lli_free; v_lli->cfg |= DMA_CHAN_CFG_DST_IO_MODE | DMA_CHAN_CFG_SRC_LINEAR_MODE | @@ -642,7 +641,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( sg_dma_address(sg), sg_dma_len(sg), sconfig); if (ret) - goto err_dma_free; + goto err_cur_lli_free; v_lli->cfg |= DMA_CHAN_CFG_DST_LINEAR_MODE | DMA_CHAN_CFG_SRC_IO_MODE | @@ -665,8 +664,12 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( return vchan_tx_prep(&vchan->vc, &txd->vd, flags); -err_dma_free: +err_cur_lli_free: dma_pool_free(sdev->pool, v_lli, p_lli); +err_lli_free: + for (prev = txd->v_lli; prev; prev = prev->v_lli_next) + dma_pool_free(sdev->pool, prev, virt_to_phys(prev)); + kfree(txd); return NULL; }