From patchwork Tue Oct 6 21:22:22 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Fleming X-Patchwork-Id: 52035 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n96LSd9A000820 for ; Tue, 6 Oct 2009 21:28:40 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757540AbZJFVYH (ORCPT ); Tue, 6 Oct 2009 17:24:07 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1758224AbZJFVYH (ORCPT ); Tue, 6 Oct 2009 17:24:07 -0400 Received: from 124x34x33x190.ap124.ftth.ucom.ne.jp ([124.34.33.190]:58099 "EHLO master.linux-sh.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757540AbZJFVYG (ORCPT ); Tue, 6 Oct 2009 17:24:06 -0400 Received: from localhost (unknown [127.0.0.1]) by master.linux-sh.org (Postfix) with ESMTP id ACCDF63758; Tue, 6 Oct 2009 21:22:38 +0000 (UTC) X-Quarantine-ID: <5gm0UFUEkcYX> X-Virus-Scanned: amavisd-new at linux-sh.org X-Amavis-Alert: BAD HEADER, Duplicate header field: "In-Reply-To" Received: from master.linux-sh.org ([127.0.0.1]) by localhost (master.linux-sh.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5gm0UFUEkcYX; Wed, 7 Oct 2009 06:22:38 +0900 (JST) Received: from localhost (82-38-64-26.cable.ubr06.brad.blueyonder.co.uk [82.38.64.26]) by master.linux-sh.org (Postfix) with ESMTP id 132A763777; Wed, 7 Oct 2009 06:22:37 +0900 (JST) From: Matt Fleming To: Paul Mundt Cc: linux-sh@vger.kernel.org Subject: [PATCH 02/14] sh: Plug PMB alloc memory leak Date: Tue, 6 Oct 2009 22:22:22 +0100 Message-Id: X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1db0a1123393575aec324e0d808b6369f9837fe4.1254861984.git.matt@console-pimps.org> References: <1db0a1123393575aec324e0d808b6369f9837fe4.1254861984.git.matt@console-pimps.org> In-Reply-To: References: Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index b1a714a..58f9358 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -33,6 +33,8 @@ #define NR_PMB_ENTRIES 16 +static void __pmb_unmap(struct pmb_entry *); + static struct kmem_cache *pmb_cache; static unsigned long pmb_map; @@ -218,9 +220,10 @@ static struct { long pmb_remap(unsigned long vaddr, unsigned long phys, unsigned long size, unsigned long flags) { - struct pmb_entry *pmbp; + struct pmb_entry *pmbp, *pmbe; unsigned long wanted; int pmb_flags, i; + long err; /* Convert typical pgprot value to the PMB equivalent */ if (flags & _PAGE_CACHABLE) { @@ -236,20 +239,22 @@ long pmb_remap(unsigned long vaddr, unsigned long phys, again: for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) { - struct pmb_entry *pmbe; int ret; if (size < pmb_sizes[i].size) continue; pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag); - if (IS_ERR(pmbe)) - return PTR_ERR(pmbe); + if (IS_ERR(pmbe)) { + err = PTR_ERR(pmbe); + goto out; + } ret = set_pmb_entry(pmbe); if (ret != 0) { pmb_free(pmbe); - return -EBUSY; + err = -EBUSY; + goto out; } phys += pmb_sizes[i].size; @@ -270,6 +275,12 @@ again: goto again; return wanted - size; + +out: + if (pmbp) + __pmb_unmap(pmbp); + + return err; } void pmb_unmap(unsigned long addr) @@ -283,12 +294,19 @@ void pmb_unmap(unsigned long addr) if (unlikely(!pmbe)) return; + __pmb_unmap(pmbe); +} + +static void __pmb_unmap(struct pmb_entry *pmbe) +{ WARN_ON(!test_bit(pmbe->entry, &pmb_map)); do { struct pmb_entry *pmblink = pmbe; - clear_pmb_entry(pmbe); + if (pmbe->entry != PMB_NO_ENTRY) + clear_pmb_entry(pmbe); + pmbe = pmblink->link; pmb_free(pmblink);