From patchwork Tue Sep 25 08:57:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Inderpal Singh X-Patchwork-Id: 11707 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 19A5D23EFB for ; Tue, 25 Sep 2012 08:57:56 +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 B1360A19039 for ; Tue, 25 Sep 2012 08:57:55 +0000 (UTC) Received: by mail-ie0-f180.google.com with SMTP id e10so12262301iej.11 for ; Tue, 25 Sep 2012 01:57:55 -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=JjY8Nx/rdFg4q9L2iw0F8hawHIodUIWgzQU5iTEK1kY=; b=o1O1Ll4RHbXYbL8krCZ50MqKjSh5E6ZYR9qbsb52McMa8zyvd+JnNDkE3cCOAftpJ7 oZs+0LbDDEq3SgI53dSnJOX7yk2M2VpV1/Et3zH1LqYp6wI74bEnEly4+gj1kkZGqh2i 6A6RtDQDUP1iLyBy8MOfnBoPAgKo3zstIgHxxAca6x9+ydRp9lt15RhKZlscHW0cOnT9 uMXMUfO6JSq1QmUq+x3CrufMUOHqTCkvnJHoby9Ac7DWOEoSXnv56jMxzQXLuOwEvPUG VH797DHcDnoQxQrOVNZJEt40to2MC0RvQn2f92nCOsF6/8XeVYNRpjoRPv7EHct/N5zB x49Q== Received: by 10.42.84.69 with SMTP id k5mr11655260icl.5.1348563475426; Tue, 25 Sep 2012 01:57:55 -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 ex8csp283042igc; Tue, 25 Sep 2012 01:57:55 -0700 (PDT) Received: by 10.68.212.70 with SMTP id ni6mr43938278pbc.22.1348563474642; Tue, 25 Sep 2012 01:57:54 -0700 (PDT) Received: from mail-pb0-f50.google.com (mail-pb0-f50.google.com [209.85.160.50]) by mx.google.com with ESMTPS id ou2si65151pbb.20.2012.09.25.01.57.54 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 25 Sep 2012 01:57:54 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.160.50 is neither permitted nor denied by best guess record for domain of inderpal.singh@linaro.org) client-ip=209.85.160.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.160.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-pb0-f50.google.com with SMTP id wz7so110925pbc.37 for ; Tue, 25 Sep 2012 01:57:54 -0700 (PDT) Received: by 10.66.74.74 with SMTP id r10mr39025441pav.57.1348563474395; Tue, 25 Sep 2012 01:57:54 -0700 (PDT) Received: from inder-ubuntu.sisodomain.com ([115.113.119.130]) by mx.google.com with ESMTPS id rr6sm21523pbc.47.2012.09.25.01.57.51 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 25 Sep 2012 01:57:53 -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 2/3] DMA: PL330: Change allocation method to properly free DMA descriptors Date: Tue, 25 Sep 2012 14:27:35 +0530 Message-Id: <1348563456-30569-3-git-send-email-inderpal.singh@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1348563456-30569-1-git-send-email-inderpal.singh@linaro.org> References: <1348563456-30569-1-git-send-email-inderpal.singh@linaro.org> X-Gm-Message-State: ALoCoQnjernjTaG+vxGfPEsR3fHAIrTNfK05kZhhLqdMxmhT5tXPZP7wSrIQJZ1i0ISr9aRKu+Dx 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 | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 10c6b6a..04d83e6 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2541,20 +2541,19 @@ 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; - 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); + desc = kmalloc(sizeof(*desc), flg); + if (!desc) + break; + _init_desc(desc); + list_add_tail(&desc->node, &pdmac->desc_pool); } spin_unlock_irqrestore(&pdmac->pool_lock, flags); - return count; + return i; } static struct dma_pl330_desc * @@ -2857,6 +2856,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 +2978,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 +3000,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 +3022,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);