Commit 06a7643c authored by Artem Bityutskiy's avatar Artem Bityutskiy Committed by David Woodhouse

[MTD] [NAND] fix race in nand_base.c

When we mark block bad we have to get chip because this involves
writing to the page's OOB. We hit this bug in UBI - we observed
random obscure crashes when it marks block bad from the background
thread and there is some parallel task which utilizes flash.

This patch also adds a TODO note about BBT table protection which
it seems does not exist.
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent 9d7b4b55
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
* if we have HW ecc support. * if we have HW ecc support.
* The AG-AND chips have nice features for speed improvement, * The AG-AND chips have nice features for speed improvement,
* which are not supported yet. Read / program 4 pages in one go. * which are not supported yet. Read / program 4 pages in one go.
* BBT table is not serialized, has to be fixed
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -360,6 +361,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) ...@@ -360,6 +361,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
/* We write two bytes, so we dont have to mess with 16 bit /* We write two bytes, so we dont have to mess with 16 bit
* access * access
*/ */
nand_get_device(chip, mtd, FL_WRITING);
ofs += mtd->oobsize; ofs += mtd->oobsize;
chip->ops.len = chip->ops.ooblen = 2; chip->ops.len = chip->ops.ooblen = 2;
chip->ops.datbuf = NULL; chip->ops.datbuf = NULL;
...@@ -367,9 +369,11 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) ...@@ -367,9 +369,11 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
chip->ops.ooboffs = chip->badblockpos & ~0x01; chip->ops.ooboffs = chip->badblockpos & ~0x01;
ret = nand_do_write_oob(mtd, ofs, &chip->ops); ret = nand_do_write_oob(mtd, ofs, &chip->ops);
nand_release_device(mtd);
} }
if (!ret) if (!ret)
mtd->ecc_stats.badblocks++; mtd->ecc_stats.badblocks++;
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment