From patchwork Sun Apr 28 13:51:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: pekon gupta X-Patchwork-Id: 240250 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 071072C00A1 for ; Sun, 28 Apr 2013 23:51:53 +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 1UWS0i-0001VX-Li; Sun, 28 Apr 2013 13:51:25 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UWS0g-0002Hl-Hp; Sun, 28 Apr 2013 13:51:22 +0000 Received: from arroyo.ext.ti.com ([192.94.94.40]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UWS0e-0002HS-Hh for linux-mtd@lists.infradead.org; Sun, 28 Apr 2013 13:51:21 +0000 Received: from dbdlxv05.itg.ti.com ([172.24.171.60]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id r3SDpH2T017799 for ; Sun, 28 Apr 2013 08:51:18 -0500 Received: from DBDE73.ent.ti.com (dbde73.ent.ti.com [172.24.171.98]) by dbdlxv05.itg.ti.com (8.14.3/8.13.8) with ESMTP id r3SDpEas008206 for ; Sun, 28 Apr 2013 08:51:16 -0500 Received: from dbdp33.itg.ti.com (172.24.170.252) by DBDE73.ent.ti.com (172.24.171.98) with Microsoft SMTP Server id 14.2.342.3; Sun, 28 Apr 2013 21:51:14 +0800 Received: from psplinux064.india.ti.com (smtpvbd.itg.ti.com [172.24.170.250]) by dbdp33.itg.ti.com (8.13.8/8.13.8) with ESMTP id r3SDpDM0018102; Sun, 28 Apr 2013 19:21:14 +0530 From: "Gupta, Pekon" To: Subject: [PATCH] UBI: optimize vid-header IO read checks Date: Sun, 28 Apr 2013 19:21:09 +0530 Message-ID: <1367157069-18994-1-git-send-email-pekon@ti.com> X-Mailer: git-send-email 1.8.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130428_095120_690410_41F15297 X-CRM114-Status: GOOD ( 14.99 ) X-Spam-Score: -9.3 (---------) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-9.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [192.94.94.40 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -2.4 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: "Gupta, Pekon" 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: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: "Gupta, Pekon" This patch is extension of earlier patch 'UBI: optimize erase-header IO read checksUBI' During mounting of UBI device, ec_hdr and vid_hdr of all PEB are scanned. This patch tries to reduce the PEB scan time, by optimizing ubi_io_read_vid_hdr based on following analysis. -------------------------------------------------------------------------- EC_HDR VID_HDR CONCLUSION NEXT STEP -------------------------------------------------------------------------- valid valid PEB contains data map PEB to corresponding LEB valid blank PEB is free attach to free list valid invalid PEB may contain data try recovering data invalid valid PEB may contain data try recovering data invalid blank PEB is free[1] schedule for erasure invalid invalid underministic schedule for erasure -------------------------------------------------------------------------- EC_HDR or VID_HDR may read 'invalid' due to following reasons: (a) contains non-UBI data. (b) block is completely erased. (b) header corrupted due to power-failure during program or erase operation. (c) header corrupted due to bitflips after program or erase operation. Signed-off-by: Gupta, Pekon --- drivers/mtd/ubi/io.c | 110 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 42 deletions(-) diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 0b9b0af..1446137 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -532,7 +532,7 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) */ err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR || - err1 == UBI_IO_FF) { + err1 == UBI_IO_FF || err1 == UBI_IO_FF_BITFLIPS) { struct ubi_ec_hdr ec_hdr; err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0); @@ -829,7 +829,6 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, { int err; uint32_t crc; - dbg_io("write EC header to PEB %d", pnum); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); @@ -998,60 +997,87 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, p = (char *)vid_hdr - ubi->vid_hdr_shift; read_err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, ubi->vid_hdr_alsize); - if (read_err && read_err != UBI_IO_BITFLIPS && !mtd_is_eccerr(read_err)) - return read_err; - - magic = be32_to_cpu(vid_hdr->magic); - if (magic != UBI_VID_HDR_MAGIC) { - if (mtd_is_eccerr(read_err)) + switch (read_err) { + case -EBADMSG: + /* un-correctable bit-flips detected + * Case-1: hdr_crc != crc(vid_hdr) + * uncorrectable bit-flips detected within header region. + * header data cannot be trusted. + * Case-2: hdr_crc == crc(vid_hdr) + * uncorrectable bit-flip do not effect header region. + * header data can be parsed. + */ + crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); + hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); + if (hdr_crc == crc) + goto good_vid_hdr; + else return UBI_IO_BAD_HDR_EBADMSG; + break; - if (ubi_check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { + case 0: + case UBI_IO_BITFLIPS: + /* check whether this is UBI vid-hdr */ + magic = be32_to_cpu(vid_hdr->magic); + if (magic == UBI_VID_HDR_MAGIC) { + /* check hdr-crc (data integrity check) */ + crc = crc32(UBI_CRC32_INIT, vid_hdr, + UBI_VID_HDR_SIZE_CRC); + hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); + if (hdr_crc == crc) { + goto good_vid_hdr; + } else { + if (verbose) { + ubi_warn("bad vid_hdr CRC at PEB %d", + pnum); + ubi_dump_vid_hdr(vid_hdr); + } + ubi_warn("bad vid_hdr CRC at PEB %d", pnum); + if (read_err) + return UBI_IO_BAD_HDR_EBADMSG; + else + return UBI_IO_BAD_HDR; + } + + /* BUT UNLIKE EC_HDR, we need to explicit check for + * vid-hdr(data) == all(0xFF) because vid_hdr is written only + * when PEB is mapped to LEB, Thus valid free PEB will still + * have blank vid_hdr. + */ + } else if (ubi_check_pattern(vid_hdr, 0xFF, + UBI_VID_HDR_SIZE)) { if (verbose) - ubi_warn("no VID header found at PEB %d, only 0xFF bytes", - pnum); - dbg_bld("no VID header found at PEB %d, only 0xFF bytes", - pnum); - if (!read_err) - return UBI_IO_FF; - else - return UBI_IO_FF_BITFLIPS; - } + ubi_warn("No vid_hdr found at PEB %d", pnum); + dbg_bld("No vid_hdr found at PEB %d", pnum); + return (read_err) ? UBI_IO_FF_BITFLIPS : UBI_IO_FF; - if (verbose) { - ubi_warn("bad magic number at PEB %d: %08x instead of %08x", - pnum, magic, UBI_VID_HDR_MAGIC); - ubi_dump_vid_hdr(vid_hdr); + /* its a programmed page, but does not contain UBI vid_hdr */ + } else { + if (verbose) { + ubi_warn("invalid vid_hdr at PEB %d", pnum); + ubi_dump_vid_hdr(vid_hdr); + } + dbg_bld("invalid vid_hdr at PEB %d", pnum); + return UBI_IO_BAD_HDR_EBADMSG; } - dbg_bld("bad magic number at PEB %d: %08x instead of %08x", - pnum, magic, UBI_VID_HDR_MAGIC); - return UBI_IO_BAD_HDR; - } - - crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); - hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); + break; - if (hdr_crc != crc) { - if (verbose) { - ubi_warn("bad CRC at PEB %d, calculated %#08x, read %#08x", - pnum, crc, hdr_crc); - ubi_dump_vid_hdr(vid_hdr); - } - dbg_bld("bad CRC at PEB %d, calculated %#08x, read %#08x", - pnum, crc, hdr_crc); - if (!read_err) - return UBI_IO_BAD_HDR; - else - return UBI_IO_BAD_HDR_EBADMSG; + default: + /* -EIO (may be incomplete page reads) */ + return read_err; } +good_vid_hdr: err = validate_vid_hdr(ubi, vid_hdr); if (err) { ubi_err("validation failed for PEB %d", pnum); return -EINVAL; } - return read_err ? UBI_IO_BITFLIPS : 0; + if (read_err) + return UBI_IO_BITFLIPS; + else + return 0; } /**