Skip to content

Commit

Permalink
mtd: rawnand: Ensure the number of bitflips is consistent
Browse files Browse the repository at this point in the history
The main NAND read page function can loop over "page reads" many times
in if the reading reports uncorrectable error(s) and if the chip
supports the read_retry feature.

In this case, the number of bitflips is summarized between
attempts. Fix this by re-initializing the entire mtd_ecc_stats object
each time we retry.

Suggested-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Link: https://lore.kernel.org/linux-mtd/20200519074549.23673-4-miquel.raynal@bootlin.com
  • Loading branch information
Miquel Raynal committed May 24, 2020
1 parent 1759279 commit 0651ed5
Showing 1 changed file with 5 additions and 5 deletions.
10 changes: 5 additions & 5 deletions drivers/mtd/nand/raw/nand_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -3295,7 +3295,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
oob_required = oob ? 1 : 0;

while (1) {
unsigned int ecc_failures = mtd->ecc_stats.failed;
struct mtd_ecc_stats ecc_stats = mtd->ecc_stats;

bytes = min(mtd->writesize - col, readlen);
aligned = (bytes == mtd->writesize);
Expand Down Expand Up @@ -3346,7 +3346,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
*/
if (use_bounce_buf) {
if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
!(mtd->ecc_stats.failed - ecc_failures) &&
!(mtd->ecc_stats.failed - ecc_stats.failed) &&
(ops->mode != MTD_OPS_RAW)) {
chip->pagecache.page = realpage;
chip->pagecache.bitflips = ret;
Expand All @@ -3369,16 +3369,16 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,

nand_wait_readrdy(chip);

if (mtd->ecc_stats.failed - ecc_failures) {
if (mtd->ecc_stats.failed - ecc_stats.failed) {
if (retry_mode + 1 < chip->read_retries) {
retry_mode++;
ret = nand_setup_read_retry(chip,
retry_mode);
if (ret < 0)
break;

/* Reset failures; retry */
mtd->ecc_stats.failed = ecc_failures;
/* Reset ecc_stats; retry */
mtd->ecc_stats = ecc_stats;
goto read_retry;
} else {
/* No more retry modes; real failure */
Expand Down

0 comments on commit 0651ed5

Please sign in to comment.