From patchwork Wed Feb 22 15:37:05 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: josselin.costanzi@mobile-devices.fr X-Patchwork-Id: 142502 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from merlin.infradead.org (unknown [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E48B5B6EF3 for ; Thu, 23 Feb 2012 02:39:33 +1100 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1S0EGG-0001sR-Mj; Wed, 22 Feb 2012 15:37:44 +0000 Received: from mail-wi0-f177.google.com ([209.85.212.177]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1S0EG7-0001rr-OR for linux-mtd@lists.infradead.org; Wed, 22 Feb 2012 15:37:39 +0000 Received: by wico1 with SMTP id o1so133644wic.36 for ; Wed, 22 Feb 2012 07:37:32 -0800 (PST) Received-SPF: pass (google.com: domain of josselin.costanzi@mobile-devices.fr designates 10.216.135.214 as permitted sender) client-ip=10.216.135.214; Authentication-Results: mr.google.com; spf=pass (google.com: domain of josselin.costanzi@mobile-devices.fr designates 10.216.135.214 as permitted sender) smtp.mail=josselin.costanzi@mobile-devices.fr Received: from mr.google.com ([10.216.135.214]) by 10.216.135.214 with SMTP id u64mr9180818wei.58.1329925052990 (num_hops = 1); Wed, 22 Feb 2012 07:37:32 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=gamma; h=mime-version:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state; bh=JIGyFXCcB0dsMCSVN3IXrPdgyq7e2tTfRNsYabUNTZk=; b=U7F3by5DSKzqkLn+BVo0SslVE2cMnKfhzozIuAHg+oRxtjeF+wxIwjAC6zKjmzMkoR /is6ZlF+g578ItNGEL8CoLSzTIkVoU+JsabWl9mPQYVNNy/6iw/OGuQ72BsXTE2/Wfms 8xdxIkP5vDEbY7p/6BxmxffGiC4MZCxcvJlE4= MIME-Version: 1.0 Received: by 10.216.135.214 with SMTP id u64mr7583409wei.58.1329925052876; Wed, 22 Feb 2012 07:37:32 -0800 (PST) Received: from localhost.localdomain (ram94-11-88-187-113-157.fbx.proxad.net. [88.187.113.157]) by mx.google.com with ESMTPS id h19sm29887346wiw.9.2012.02.22.07.37.31 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 22 Feb 2012 07:37:32 -0800 (PST) From: josselin.costanzi@mobile-devices.fr To: linux-mtd@lists.infradead.org Subject: [PATCH] UBI: allocate verification buffer on demand Date: Wed, 22 Feb 2012 16:37:05 +0100 Message-Id: <4f450bbc.334cb40a.7321.64ad@mx.google.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1329925025-4980-1-git-send-email-y> References: <1329925025-4980-1-git-send-email-y> X-Gm-Message-State: ALoCoQn7Sb5F4DcUbbykwETtYLmKcltrxNhAIY7myJCt1JQDCVmR6nWdFodwnL2L8IvN1b12qp6m X-Spam-Note: CRM114 invocation failed X-Spam-Score: -1.8 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.8 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.212.177 listed in list.dnswl.org] 0.8 SPF_NEUTRAL SPF: sender does not match SPF record (neutral) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Josselin Costanzi X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Josselin Costanzi Instead of using pre-allocated 'ubi->peb_buf2' buffer in 'ubi_eba_copy_leb()', dynamically allocate it when needed. The intent is to get rid of the pre-allocated 'ubi->peb_buf2' buffer and save up to 2MiB of RAM per attached device (or more if PEB size is larger). If the allocation fails, we fallback to a degraded mode where data integrity is still ensured, at the cost of higher CPU usage. --- drivers/mtd/ubi/build.c | 6 ------ drivers/mtd/ubi/eba.c | 31 +++++++++++++++++++++++++++---- drivers/mtd/ubi/ubi.h | 4 +--- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 115749f..6e0806b 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -949,10 +949,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) if (!ubi->peb_buf1) goto out_free; - ubi->peb_buf2 = vmalloc(ubi->peb_size); - if (!ubi->peb_buf2) - goto out_free; - err = ubi_debugging_init_dev(ubi); if (err) goto out_free; @@ -1030,7 +1026,6 @@ out_debugging: ubi_debugging_exit_dev(ubi); out_free: vfree(ubi->peb_buf1); - vfree(ubi->peb_buf2); if (ref) put_device(&ubi->dev); else @@ -1102,7 +1097,6 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) put_mtd_device(ubi->mtd); ubi_debugging_exit_dev(ubi); vfree(ubi->peb_buf1); - vfree(ubi->peb_buf2); ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); put_device(&ubi->dev); return 0; diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index cd26da8..b18ca27 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -985,9 +985,10 @@ static int is_error_sane(int err) int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, struct ubi_vid_hdr *vid_hdr) { - int err, vol_id, lnum, data_size, aldata_size, idx; + int err, vol_id, lnum, data_size, aldata_size, idx, res; struct ubi_volume *vol; - uint32_t crc; + uint32_t crc, crc_read; + void *p, *peb_buf2; vol_id = be32_to_cpu(vid_hdr->vol_id); lnum = be32_to_cpu(vid_hdr->lnum); @@ -1121,6 +1122,19 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, } if (data_size > 0) { + /* + * We want that buffer to check we wrote the data correctly. + * If we can't allocate it, we will check the data we wrote + * using crc32. + */ + peb_buf2 = vmalloc(ubi->peb_size); + if (!peb_buf2) { + dbg_wl("Can't allocate verification buffer, will work " + "in degraded mode"); + p = ubi->peb_buf1; + } else + p = peb_buf2; + err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); if (err) { if (err == -EIO) @@ -1135,7 +1149,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, * sure it was written correctly. */ - err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size); + err = ubi_io_read_data(ubi, p, to, 0, aldata_size); if (err) { if (err != UBI_IO_BITFLIPS) { ubi_warn("error %d while reading data back " @@ -1149,7 +1163,14 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, cond_resched(); - if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { + if (peb_buf2) { + res = memcmp(ubi->peb_buf1, peb_buf2, aldata_size); + } else { + crc_read = crc32(UBI_CRC32_INIT, p, data_size); + res = (crc != crc_read); + } + + if (res) { ubi_warn("read data back from PEB %d and it is " "different", to); err = -EINVAL; @@ -1164,6 +1185,8 @@ out_unlock_buf: mutex_unlock(&ubi->buf_mutex); out_unlock_leb: leb_write_unlock(ubi, vol_id, lnum); + if (peb_buf2) + vfree(peb_buf2); return err; } diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index d51d75d..cb93ad9 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -388,8 +388,7 @@ struct ubi_wl_entry; * @mtd: MTD device descriptor * * @peb_buf1: a buffer of PEB size used for different purposes - * @peb_buf2: another buffer of PEB size used for different purposes - * @buf_mutex: protects @peb_buf1 and @peb_buf2 + * @buf_mutex: protects @peb_buf1 * @ckvol_mutex: serializes static volume checking when opening * * @dbg: debugging information for this UBI device @@ -472,7 +471,6 @@ struct ubi_device { struct mtd_info *mtd; void *peb_buf1; - void *peb_buf2; struct mutex buf_mutex; struct mutex ckvol_mutex;