From patchwork Mon May 27 08:02:24 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Weber X-Patchwork-Id: 246546 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:770:15f::2]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 86B312C0209 for ; Mon, 27 May 2013 18:06:40 +1000 (EST) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UgsRR-0003Xx-Gv; Mon, 27 May 2013 08:06:05 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UgsRP-0000SB-8z; Mon, 27 May 2013 08:06:03 +0000 Received: from moutng.kundenserver.de ([212.227.17.10]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UgsRC-0000Rg-20 for linux-mtd@lists.infradead.org; Mon, 27 May 2013 08:05:50 +0000 Received: from mail.er.corscience.de (DSL01.212.114.252.242.ip-pool.NEFkom.net [212.114.252.242]) by mrelayeu.kundenserver.de (node=mreu3) with ESMTP (Nemesis) id 0LaNXn-1U1XGM2jT5-00mJin; Mon, 27 May 2013 10:04:46 +0200 Received: from lupus.er.corscience.de (lupus.2og.er.corscience.de [192.168.102.101]) by mail.er.corscience.de (Postfix) with ESMTP id 6E970478001; Mon, 27 May 2013 10:04:36 +0200 (CEST) From: Thomas Weber To: Subject: [PATCH] UBI: Fastmap: Fix memory leak Date: Mon, 27 May 2013 10:02:24 +0200 Message-Id: <1369641744-13534-1-git-send-email-thomas@tomweber.eu> X-Mailer: git-send-email 1.8.2.3 In-Reply-To: References: X-Provags-ID: V02:K0:t6+mW4/3qAAg8+463YMuRC9+R756AeRZSj5YcGQ70TW FLv7daVs/lcTWKehCrBRJft48qBzDIKt9ibwuXaEja/cb2eoZp nwEWFTFzcR8XGA81UJChk23+RcBlDjp8dU8C2Lls/6MmqgvuWu esQfxHuqnVKw02Ara/k7DgM3VEKhhkJyyIsYtNrV211M16TCB1 yNrEZ77dPkckwiYzgSjCiT5RUjH6SbB42PgohBacOMFHEPf/7E seWKgybcVfQVbV6+mH5jrcZzt7m4oyAuiuejzm3mNrN9WqEqqz etvmPsbXJHsIniH33Qr+PZSPCE6w8gIwH6hQHRcUKU1APul+WW efOTaOVuCoA0aSMTwMaWYT5AlUYVBIMoCWF0QaaEjbnoQSk9Hj E9ZbKyR4VY4hXTkzT9bAB9Lm+kyw2x/QFA= X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130527_040550_313621_C9F24DFE X-CRM114-Status: GOOD ( 13.77 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [212.227.17.10 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Artem Bityutskiy , Richard Weinberger , linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, wang bo , David Woodhouse , Thomas Weber X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Signed-off-by: wang bo [fix whitespace errors] Tested with linux-v3.10-rc3 on Devkit8000. Signed-off-by: Thomas Weber The discussion about this patch can be found: https://lkml.org/lkml/2013/5/2/118 This patches fixes the following bug for me: When CONFIG_DEBUG_VM is active and making ubiattach ... ; ubidetach...; ubiattach ... the second ubiattach stops with: [ 37.918304] UBI: default fastmap pool size: 95 [ 37.923004] UBI: default fastmap WL pool size: 25 [ 37.928741] UBI: attaching mtd4 to ubi0 [ 37.933197] kmem_cache_sanity_check (ubi_aeb_slab_cache): Cache name already exists. [ 37.941864] CPU: 0 PID: 757 Comm: ubiattach Not tainted 3.10.0-rc3 #66 [ 37.949066] [] (unwind_backtrace+0x0/0xec) from [] (show_stack+0x20/0x24) [ 37.958343] [] (show_stack+0x20/0x24) from [] (dump_stack+0x20/0x28) [ 37.967163] [] (dump_stack+0x20/0x28) from [] (kmem_cache_create_memcg+0x120/0x2a4) [ 37.977478] [] (kmem_cache_create_memcg+0x120/0x2a4) from [] (kmem_cache_create+0x48/0x50) [ 37.988281] [] (kmem_cache_create+0x48/0x50) from [] (alloc_ai+0x84/0xb0) [ 37.997528] [] (alloc_ai+0x84/0xb0) from [] (ubi_attach+0x28/0x34c) [ 38.006225] [] (ubi_attach+0x28/0x34c) from [] (ubi_attach_mtd_dev+0x69c/0xca4) [ 38.016021] [] (ubi_attach_mtd_dev+0x69c/0xca4) from [] (ctrl_cdev_ioctl+0xe4/0x190) [ 38.026275] [] (ctrl_cdev_ioctl+0xe4/0x190) from [] (do_vfs_ioctl+0x554/0x5c4) [ 38.035980] [] (do_vfs_ioctl+0x554/0x5c4) from [] (SyS_ioctl+0x4c/0x6c) [ 38.045043] [] (SyS_ioctl+0x4c/0x6c) from [] (ret_fast_syscall+0x0/0x48) [ 38.054168] UBI error: ubi_attach_mtd_dev: failed to attach mtd4, error -12 ubiattach: error!: cannot attach "/dev/mtd4" error 12 (Cannot allocate memory) --- drivers/mtd/ubi/attach.c | 58 +++++++++++++++++++++++++++-------------------- drivers/mtd/ubi/fastmap.c | 13 ----------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index c071d41..e9f64bc 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -1212,6 +1212,30 @@ static void destroy_ai(struct ubi_attach_info *ai) kfree(ai); } +static struct ubi_attach_info *alloc_ai(const char *slab_name) +{ + struct ubi_attach_info *ai; + + ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); + if (!ai) + return ai; + + INIT_LIST_HEAD(&ai->corr); + INIT_LIST_HEAD(&ai->free); + INIT_LIST_HEAD(&ai->erase); + INIT_LIST_HEAD(&ai->alien); + ai->volumes = RB_ROOT; + ai->aeb_slab_cache = kmem_cache_create(slab_name, + sizeof(struct ubi_ainf_peb), + 0, 0, NULL); + if (!ai->aeb_slab_cache) { + kfree(ai); + ai = NULL; + } + + return ai; +} + /** * scan_all - scan entire MTD device. * @ubi: UBI device description object @@ -1315,8 +1339,13 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) int err, pnum, fm_anchor = -1; unsigned long long max_sqnum = 0; + struct ubi_attach_info *fm_temp_ai = NULL; err = -ENOMEM; + fm_temp_ai = alloc_ai("ubi_scan_fastmap_slab_cache"); + if (!fm_temp_ai) + goto out; + ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); if (!ech) goto out; @@ -1331,7 +1360,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) cond_resched(); dbg_gen("process PEB %d", pnum); - err = scan_peb(ubi, ai, pnum, &vol_id, &sqnum); + err = scan_peb(ubi, fm_temp_ai, pnum, &vol_id, &sqnum); if (err < 0) goto out_vidh; @@ -1343,6 +1372,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) ubi_free_vid_hdr(ubi, vidh); kfree(ech); + destroy_ai(fm_temp_ai); if (fm_anchor < 0) return UBI_NO_FASTMAP; @@ -1351,6 +1381,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) out_vidh: ubi_free_vid_hdr(ubi, vidh); + destroy_ai(fm_temp_ai); out_ech: kfree(ech); out: @@ -1359,29 +1390,6 @@ out: #endif -static struct ubi_attach_info *alloc_ai(const char *slab_name) -{ - struct ubi_attach_info *ai; - - ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); - if (!ai) - return ai; - - INIT_LIST_HEAD(&ai->corr); - INIT_LIST_HEAD(&ai->free); - INIT_LIST_HEAD(&ai->erase); - INIT_LIST_HEAD(&ai->alien); - ai->volumes = RB_ROOT; - ai->aeb_slab_cache = kmem_cache_create(slab_name, - sizeof(struct ubi_ainf_peb), - 0, 0, NULL); - if (!ai->aeb_slab_cache) { - kfree(ai); - ai = NULL; - } - - return ai; -} /** * ubi_attach - attach an MTD device. @@ -1419,7 +1427,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) return -ENOMEM; } - err = scan_all(ubi, ai, UBI_FM_MAX_START); + err = scan_all(ubi, ai, 0); } } #else diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 0648c69..7b73d23 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -552,21 +552,8 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, INIT_LIST_HEAD(&used); INIT_LIST_HEAD(&free); INIT_LIST_HEAD(&eba_orphans); - INIT_LIST_HEAD(&ai->corr); - INIT_LIST_HEAD(&ai->free); - INIT_LIST_HEAD(&ai->erase); - INIT_LIST_HEAD(&ai->alien); - ai->volumes = RB_ROOT; ai->min_ec = UBI_MAX_ERASECOUNTER; - ai->aeb_slab_cache = kmem_cache_create("ubi_ainf_peb_slab", - sizeof(struct ubi_ainf_peb), - 0, 0, NULL); - if (!ai->aeb_slab_cache) { - ret = -ENOMEM; - goto fail; - } - fmsb = (struct ubi_fm_sb *)(fm_raw); ai->max_sqnum = fmsb->sqnum; fm_pos += sizeof(struct ubi_fm_sb);