From patchwork Fri Oct 5 10:17:54 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Inderpal Singh X-Patchwork-Id: 12000 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 394DA23EFB for ; Fri, 5 Oct 2012 10:18:09 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id E1627A1903B for ; Fri, 5 Oct 2012 10:18:08 +0000 (UTC) Received: by mail-ie0-f180.google.com with SMTP id e10so3260369iej.11 for ; Fri, 05 Oct 2012 03:18:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=VqklyAAhEy5sJgs+K7L5HedQpx6A4OUz/DDbrwyUVoY=; b=UNJ16M9mNq1OpqXEmTl569jB8wgDKF+qrGenH9X/YWuyEjWvqBFjc//WFYSg7MeC4g c4TQNFtKxlXkAhJyeL7jpWvaRQfEUlVrbSXPXx3124MWUVrqYTeoKtP4p4PNp4Oux3XS 3Z30GiNU/a/33eNl67WnHjPhUh2bp/MfX6DWKvkROuOvUcPXn7qJaRfWDLPEGMkOoOUo tbHQl2EWXWTwgJRTyf1nqFiH3/tZLYzaczfG3VWnu6vzuGstnKkMZ+3h3UiE/J5HuVdq ml55BeFgYpMAIysBkOGF9NXoChuUkqgFZcjwKxpvPdnAX2cpWlEYA1oV2nVmaP87sk48 gZyQ== Received: by 10.50.178.40 with SMTP id cv8mr739468igc.0.1349432288691; Fri, 05 Oct 2012 03:18:08 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.184.232 with SMTP id ex8csp117176igc; Fri, 5 Oct 2012 03:18:08 -0700 (PDT) Received: by 10.66.77.70 with SMTP id q6mr20595832paw.24.1349432287802; Fri, 05 Oct 2012 03:18:07 -0700 (PDT) Received: from mail-pa0-f50.google.com (mail-pa0-f50.google.com [209.85.220.50]) by mx.google.com with ESMTPS id nz5si18774456pbb.316.2012.10.05.03.18.07 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 05 Oct 2012 03:18:07 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.50 is neither permitted nor denied by best guess record for domain of inderpal.singh@linaro.org) client-ip=209.85.220.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.50 is neither permitted nor denied by best guess record for domain of inderpal.singh@linaro.org) smtp.mail=inderpal.singh@linaro.org Received: by mail-pa0-f50.google.com with SMTP id hz11so1755480pad.37 for ; Fri, 05 Oct 2012 03:18:07 -0700 (PDT) Received: by 10.68.229.138 with SMTP id sq10mr29613608pbc.126.1349432287518; Fri, 05 Oct 2012 03:18:07 -0700 (PDT) Received: from inder-ubuntu.sisodomain.com ([115.113.119.130]) by mx.google.com with ESMTPS id qa4sm5848287pbb.70.2012.10.05.03.18.03 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 05 Oct 2012 03:18:06 -0700 (PDT) From: Inderpal Singh To: linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org Cc: jassisinghbrar@gmail.com, boojin.kim@samsung.com, vinod.koul@intel.com, patches@linaro.org, kgene.kim@samsung.com Subject: [PATCH v2 2/4] DMA: PL330: Change allocation method to properly free DMA descriptors Date: Fri, 5 Oct 2012 15:47:54 +0530 Message-Id: <1349432276-22919-3-git-send-email-inderpal.singh@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1349432276-22919-1-git-send-email-inderpal.singh@linaro.org> References: <1349432276-22919-1-git-send-email-inderpal.singh@linaro.org> X-Gm-Message-State: ALoCoQk9JSe9bXp83s1JFl9a58PBQqbfTkfy4odh+dFqS6RKDCcuAQjVciyiLn8MXaC80R9owKwm In probe, memory for multiple DMA descriptors were being allocated at once and then it was being split and added into DMA pool one by one. The address of this memory allocation is not being saved anywhere. To free this memory, the address is required. Initially the first node of the pool will be pointed by this address but as we use this pool the descs will shuffle and hence we will lose the track of the address. This patch does following: 1. Allocates DMA descs one by one and then adds them to pool so that all descs can be fetched and memory freed one by one. This way runtime added descs can also be freed. 2. Free DMA descs in case of error in probe and in module's remove function Signed-off-by: Inderpal Singh --- drivers/dma/pl330.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 10c6b6a..bf71ff7 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2541,20 +2541,20 @@ static int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) if (!pdmac) return 0; - desc = kmalloc(count * sizeof(*desc), flg); - if (!desc) - return 0; + for (i = 0; i < count; i++) { + desc = kmalloc(sizeof(*desc), flg); + if (!desc) + break; + _init_desc(desc); - spin_lock_irqsave(&pdmac->pool_lock, flags); + spin_lock_irqsave(&pdmac->pool_lock, flags); - for (i = 0; i < count; i++) { - _init_desc(&desc[i]); - list_add_tail(&desc[i].node, &pdmac->desc_pool); - } + list_add_tail(&desc->node, &pdmac->desc_pool); - spin_unlock_irqrestore(&pdmac->pool_lock, flags); + spin_unlock_irqrestore(&pdmac->pool_lock, flags); + } - return count; + return i; } static struct dma_pl330_desc * @@ -2857,6 +2857,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) struct dma_pl330_platdata *pdat; struct dma_pl330_dmac *pdmac; struct dma_pl330_chan *pch; + struct dma_pl330_desc *desc; struct pl330_info *pi; struct dma_device *pd; struct resource *res; @@ -2978,6 +2979,12 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) probe_err5: kfree(pdmac->peripherals); probe_err4: + while (!list_empty(&pdmac->desc_pool)) { + desc = list_entry(pdmac->desc_pool.next, + struct dma_pl330_desc, node); + list_del(&desc->node); + kfree(desc); + } pl330_del(pi); probe_err3: free_irq(irq, pi); @@ -2994,6 +3001,7 @@ static int __devexit pl330_remove(struct amba_device *adev) { struct dma_pl330_dmac *pdmac = amba_get_drvdata(adev); struct dma_pl330_chan *pch, *_p; + struct dma_pl330_desc *desc; struct pl330_info *pi; struct resource *res; int irq; @@ -3015,6 +3023,13 @@ static int __devexit pl330_remove(struct amba_device *adev) pl330_free_chan_resources(&pch->chan); } + while (!list_empty(&pdmac->desc_pool)) { + desc = list_entry(pdmac->desc_pool.next, + struct dma_pl330_desc, node); + list_del(&desc->node); + kfree(desc); + } + pi = &pdmac->pif; pl330_del(pi);