linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Richard Genoud <richard.genoud@gmail.com>
To: Artem Bityutskiy <dedekind1@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>,
	linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org,
	Richard Genoud <richard.genoud@gmail.com>
Subject: [PATCH 3/4] UBI: use the whole MTD device size to get bad_peb_limit
Date: Tue, 10 Jul 2012 18:23:41 +0200	[thread overview]
Message-ID: <1341937423-16516-4-git-send-email-richard.genoud@gmail.com> (raw)
In-Reply-To: <1341937423-16516-1-git-send-email-richard.genoud@gmail.com>

On NAND flash devices, UBI reserves some physical erase blocks (PEB) for
bad block handling.
Today, the number of reserved PEB can only be set as a percentage of the
total number of PEB in each MTD partition.
For example, for a NAND flash with 128KiB PEB, 2 MTD partition of 20MiB
(mtd0) and 100MiB (mtd1) and 2% reserved PEB:
- the UBI device on mtd0 will have 2 PEB reserved
- the UBI device on mtd1 will have 16 PEB reserved

The problem with this behaviour is that NAND flash manufacturers give a
minimum number of valid block (NVB) during the endurance life of the
device.
E.G.:
Parameter             Symbol    Min    Max    Unit      Notes
--------------------------------------------------------------
Valid block number     NVB     1004    1024   Blocks     1
Note:
1. Invalid blocks are block that contain one or more bad bits beyond
ECC. The device may contain bad blocks upon shipment. Additional bad
blocks may develop over time; however, the total number of available
blocks will not drop below NVB during the endurance life of the device.

>From this number we can deduce the maximum number of bad PEB that a
device will contain during its endurance life :
A 128MiB NAND flash (1024 PEB) will not have less than 20 bad blocks
during the flash endurance life.

BUT, the manufacturer doesn't tell where those bad block will appear. He
doesn't say either if they will be equally disposed on the whole device
(and I'm pretty sure they won't).
So, according to the datasheets, we should reserve the maximum number of
bad PEB for each UBI device.
(Worst case scenario: 20 bad blocks appears on the smallest MTD
partition.)

So this patch make UBI use the whole MTD device size to calculate the
Maximum bad expected eraseblocks.

The Kconfig option is in per1024 blocks, thus it can have a default
value of 20 which is *very* common for NAND devices.

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 drivers/mtd/ubi/Kconfig |   14 ++++++++++----
 drivers/mtd/ubi/build.c |   17 ++++++++++++++---
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig
index 145cda2..b77ffe1 100644
--- a/drivers/mtd/ubi/Kconfig
+++ b/drivers/mtd/ubi/Kconfig
@@ -28,15 +28,21 @@ config MTD_UBI_WL_THRESHOLD
 	  to 128 or 256, although it does not have to be power of 2).
 
 config MTD_UBI_BEB_LIMIT
-	int "Percentage of maximum expected bad eraseblocks"
-	default 2
-	range 0 25
+	int "Maximum expected bad eraseblocks per 1024 eraseblocks"
+	default 20
+	range 2 256
 	help
 	  If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI
 	  reserves some amount of physical eraseblocks to handle new bad
 	  eraseblocks.
 	  This option specifies the maximum bad eraseblocks UBI expects on the
-	  ubi device (percents of total number of flash eraseblocks).
+	  ubi device per 1024 eraseblocks.
+	  This value is often given in an other form in the NAND datasheet
+	  (min NVB i.e. minimal number of valid blocks). The maximum expected
+	  bad eraseblocks per 1024 is then:
+	    1024 * (1 - MinNVB / MaxNVB)
+	  Which gives 20 for most NAND devices.
+
 	  This limit is used in order to derive amount of eraseblock UBI
 	  reserves for handling new bad blocks.
 	  If the device has more bad eraseblocks than this limit, UBI does not
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 62cc6ce..87b39c2 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -36,6 +36,7 @@
 #include <linux/namei.h>
 #include <linux/stat.h>
 #include <linux/miscdevice.h>
+#include <linux/mtd/partitions.h>
 #include <linux/log2.h>
 #include <linux/kthread.h>
 #include <linux/kernel.h>
@@ -610,12 +611,22 @@ static int io_init(struct ubi_device *ubi)
 	if (mtd_can_have_bb(ubi->mtd)) {
 		ubi->bad_allowed = 1;
 		if (CONFIG_MTD_UBI_BEB_LIMIT > 0) {
-			int percent = CONFIG_MTD_UBI_BEB_LIMIT;
+			int per1024 = CONFIG_MTD_UBI_BEB_LIMIT;
+			int device_peb_count;
+			uint64_t device_size;
 			int beb_limit;
 
-			beb_limit = mult_frac(ubi->peb_count, percent, 100);
+			/* we are using here the whole MTD device size and not
+			 * the MTD partition size because the maximum number of
+			 * bad blocks is a percentage of the whole device and
+			 * the bad blocks are not fairly disposed on a flash
+			 * device
+			 */
+			device_size = mtd_get_device_size(ubi->mtd);
+			device_peb_count = mtd_div_by_eb(device_size, ubi->mtd);
+			beb_limit = mult_frac(device_peb_count, per1024, 1024);
 			/* round it up */
-			if (mult_frac(beb_limit, 100, percent) < ubi->peb_count)
+			if (mult_frac(beb_limit, 1024, per1024) < ubi->peb_count)
 				beb_limit++;
 			ubi->bad_peb_limit = beb_limit;
 		}
-- 
1.7.2.5


  parent reply	other threads:[~2012-07-10 16:24 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-10 16:23 [PATCH 0/4] UBI: Use the whole NAND device to calculate max bad block number Richard Genoud
2012-07-10 16:23 ` [PATCH 1/4] mtd_is_partition: struct mtd_info should be const Richard Genoud
2012-08-15 14:02   ` Artem Bityutskiy
2012-07-10 16:23 ` [PATCH 2/4] MTD parts: introduce mtd_get_device_size() Richard Genoud
2012-07-10 16:23 ` Richard Genoud [this message]
2012-07-18  6:50   ` [PATCH 3/4] UBI: use the whole MTD device size to get bad_peb_limit Artem Bityutskiy
2012-07-18  8:30     ` Richard Genoud
2012-08-15 12:53       ` Artem Bityutskiy
2012-08-15 15:08   ` Artem Bityutskiy
2012-08-16  8:13     ` Richard Genoud
2012-08-16 12:00       ` Artem Bityutskiy
2012-08-16  8:25     ` Shmulik Ladkani
2012-08-16 10:35       ` Richard Genoud
2012-08-16 11:58         ` Artem Bityutskiy
2012-08-16 11:56       ` Artem Bityutskiy
2012-08-16  8:32     ` Shmulik Ladkani
2012-08-16 11:58       ` Artem Bityutskiy
2012-08-16 11:58       ` Richard Genoud
2012-07-10 16:23 ` [PATCH 4/4] UBI: replace MTD_UBI_BEB_LIMIT with user-space parameter Richard Genoud
2012-08-15 14:57   ` Artem Bityutskiy
2012-08-16 14:52     ` [PATCH 0/2] splitting "UBI: replace MTD_UBI_BEB_LIMIT with user-space parameter" Richard Genoud
2012-08-16 14:52     ` [PATCH 1/2] UBI: replace MTD_UBI_BEB_LIMIT with module parameter Richard Genoud
2012-08-17  8:22       ` Artem Bityutskiy
2012-08-17 10:27         ` Richard Genoud
2012-08-16 14:52     ` [PATCH 2/2] UBI: add ioctl for max_beb_per1024 Richard Genoud
2012-08-17  8:28       ` Artem Bityutskiy
2012-08-16  8:57   ` [PATCH 4/4] UBI: replace MTD_UBI_BEB_LIMIT with user-space parameter Shmulik Ladkani
2012-08-16 10:07     ` Richard Genoud
2012-08-16 10:42       ` Shmulik Ladkani
2012-08-16 13:33         ` Artem Bityutskiy
2012-08-19  7:09           ` Shmulik Ladkani
2012-08-19 19:04             ` Artem Bityutskiy
2012-08-20  6:55               ` Richard Genoud
2012-08-20  8:17                 ` Artem Bityutskiy
2012-08-20  8:27                   ` Richard Genoud
2012-08-16 13:28     ` Artem Bityutskiy
2012-08-16 13:50       ` Shmulik Ladkani
2012-08-16 14:30         ` Richard Genoud
2012-08-16 14:54           ` [PATCH] UBI: use a config value for default BEB limit Richard Genoud
2012-08-17  7:34           ` [PATCH 4/4] UBI: replace MTD_UBI_BEB_LIMIT with user-space parameter Artem Bityutskiy
2012-08-17  7:06         ` Artem Bityutskiy
2012-07-10 16:23 ` [PATCH] ubiattach: introduce max_beb_per1024 in UBI_IOCATT Richard Genoud
2012-08-17  9:37   ` Artem Bityutskiy
2012-08-16 13:10 ` [PATCH 1/2] UBI: use the whole MTD device size to get bad_peb_limit Artem Bityutskiy
2012-08-16 13:10   ` [PATCH 2/2] arm: sam9_l9260_defconfig: adjust UBI bad eraseblocks limit Artem Bityutskiy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1341937423-16516-4-git-send-email-richard.genoud@gmail.com \
    --to=richard.genoud@gmail.com \
    --cc=dedekind1@gmail.com \
    --cc=dwmw2@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).