Skip to contentSkip to conversation

mtd: nand: Properly initialize 'mtd->bitflip_threshold' prior 'scan_bbt()' is invoked

PATCH In review Shmulik Ladkani 6 participants 6 messages Jun 8, 2012 – Jun 9, 2012

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mtd: nand: Properly initialize 'mtd->bitflip_threshold' prior 'scan_bbt()' is invoked

As of edbc454 [mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN], 'mtd->bitflip_threshold' must be set for mtd devices having ECC, prior any 'mtd_read()' call.
Otherwise, 'mtd_read()' will falsely return -EUCLEAN.

Normally, 'mtd->bitflip_threshold' is initialized when the MTD is added.

However, this is too late for NAND MTDs, as 'scan_bbt()' is invoked prior the existing initialization of 'mtd->bitflip_threshold'.

This is a problem since 'scan_bbt()' calls 'mtd_read()', in the case of a flash-based bad block table.
It resulted in a falsely reported bitflips indication during BBT read, which lead to constant scrubbing of the flash BBT blocks.

Initialize 'mtd->bitflip_threshold' to its default value (if not already set by the driver), prior invocation of 'scan_bbt()'.

---
- The issue was introduced in 3.5-rc1 and needs to be merged before 3.5
- Sascha, I've credited you as the reporter, is that ok?
- Sascha, care to test and verify it works for your system?

drivers/mtd/nand/nand_base.c +7 -0
index 61805e7..0a8724e 100644
@@ -3484,6 +3484,13 @@ int nand_scan_tail(struct mtd_info *mtd)
 	/* propagate ecc info to mtd_info */
 	mtd->ecclayout = chip->ecc.layout;
 	mtd->ecc_strength = chip->ecc.strength;
+	/*
+	 * Initialize bitflip_threshold to its default prior scan_bbt() call.
+	 * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be
+	 * properly set.
+	 */
+	if (!mtd->bitflip_threshold)
+		mtd->bitflip_threshold = mtd->ecc_strength;
 
 	/* Check, if we should skip the bad block table scan */
 	if (chip->options & NAND_SKIP_BBTSCAN)
Signature · 1 line
1.7.5.4
#1 lore raw

Artem, David,

Patch was accidentally submitted twice.

Disregard this post please.

Sorry for the inconvenience.

Regards,
Shmulik

Quoted 20 lines · On Fri, 8 Jun 2012 18:29:06 +0300 Shmulik Ladkani <[email protected]> wrote:

As of edbc454 [mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN], 'mtd->bitflip_threshold' must be set for mtd devices having ECC, prior any 'mtd_read()' call.
Otherwise, 'mtd_read()' will falsely return -EUCLEAN.

Normally, 'mtd->bitflip_threshold' is initialized when the MTD is added.

However, this is too late for NAND MTDs, as 'scan_bbt()' is invoked prior the existing initialization of 'mtd->bitflip_threshold'.

This is a problem since 'scan_bbt()' calls 'mtd_read()', in the case of a flash-based bad block table.
It resulted in a falsely reported bitflips indication during BBT read, which lead to constant scrubbing of the flash BBT blocks.

Initialize 'mtd->bitflip_threshold' to its default value (if not already set by the driver), prior invocation of 'scan_bbt()'.

#2 lore raw
In reply to Shmulik Ladkani
Quoted 4 lines · Shmulik Ladkani

As of edbc454 [mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN], 'mtd->bitflip_threshold' must be set for mtd devices having ECC, prior any 'mtd_read()' call.
Otherwise, 'mtd_read()' will falsely return -EUCLEAN.

Pushed to l2-mtd.git, thanks! Sascha - does it fix the issue for you?

Signature · 2 lines
Best Regards,
Artem Bityutskiy
Tested-by on v1 1/1
#3 lore raw
In reply to Shmulik Ladkani
Quoted 15 lines · Shmulik Ladkani

As of edbc454 [mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN], 'mtd->bitflip_threshold' must be set for mtd devices having ECC, prior any 'mtd_read()' call.
Otherwise, 'mtd_read()' will falsely return -EUCLEAN.

Normally, 'mtd->bitflip_threshold' is initialized when the MTD is added.

However, this is too late for NAND MTDs, as 'scan_bbt()' is invoked prior the existing initialization of 'mtd->bitflip_threshold'.

This is a problem since 'scan_bbt()' calls 'mtd_read()', in the case of a flash-based bad block table.
It resulted in a falsely reported bitflips indication during BBT read, which lead to constant scrubbing of the flash BBT blocks.

Quoted 8 lines

Initialize 'mtd->bitflip_threshold' to its default value (if not already set by the driver), prior invocation of 'scan_bbt()'.

---
- The issue was introduced in 3.5-rc1 and needs to be merged before 3.5
- Sascha, I've credited you as the reporter, is that ok?

Sure, that's ok.

Quoted 1 line

- Sascha, care to test and verify it works for your system?

Yes, this puts my system back to work

Quoted 22 lines
drivers/mtd/nand/nand_base.c +7 -0
index 61805e7..0a8724e 100644
@@ -3484,6 +3484,13 @@ int nand_scan_tail(struct mtd_info *mtd)
 	/* propagate ecc info to mtd_info */
 	mtd->ecclayout = chip->ecc.layout;
 	mtd->ecc_strength = chip->ecc.strength;
+	/*
+	 * Initialize bitflip_threshold to its default prior scan_bbt() call.
+	 * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be
+	 * properly set.
+	 */
+	if (!mtd->bitflip_threshold)
+		mtd->bitflip_threshold = mtd->ecc_strength;
 
 	/* Check, if we should skip the bad block table scan */
 	if (chip->options & NAND_SKIP_BBTSCAN)
Signature · 1 line
1.7.5.4
Signature · 4 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
#4 lore raw
Quoted 5 lines · Sascha Hauer
Quoted 2 lines

- The issue was introduced in 3.5-rc1 and needs to be merged before

3.5

Quoted 1 line

- Sascha, I've credited you as the reporter, is that ok?

Quoted 7 lines

Sure, that's ok.

Quoted 1 line

- Sascha, care to test and verify it works for your system?

Yes, this puts my system back to work

Thanks. I've pushed this to linux-mtd.git and will ask Linus to pull it shortly.

Signature · 1 line
dwmw2
Reviewed-by on v1 1/1
#5 lore raw
In reply to Shmulik Ladkani
Quoted 10 lines · Shmulik Ladkani

As of edbc454 [mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN], 'mtd->bitflip_threshold' must be set for mtd devices having ECC, prior any 'mtd_read()' call.
Otherwise, 'mtd_read()' will falsely return -EUCLEAN.

Normally, 'mtd->bitflip_threshold' is initialized when the MTD is added.

However, this is too late for NAND MTDs, as 'scan_bbt()' is invoked prior the existing initialization of 'mtd->bitflip_threshold'.

Quoted 8 lines

This is a problem since 'scan_bbt()' calls 'mtd_read()', in the case of a flash-based bad block table.
It resulted in a falsely reported bitflips indication during BBT read, which lead to constant scrubbing of the flash BBT blocks.

Initialize 'mtd->bitflip_threshold' to its default value (if not already set by the driver), prior invocation of 'scan_bbt()'.

(FWIW).

Thanks again Shmulik!

I do think that the patch to the bad block management code that I sent yesterday should be merged as well. That would also fix the problem, but it is really a separate issue. Currently ecc errors are ignored during the BBT creation for some configurations but not for others (like that of the mxc_nand controller). It looks like an oversight that they are not ignored, and it makes sense to ignore them, since there's not much you can do about them at that time, and the functions higher up the call stack don't try to.

Thanks,
Mike