From: Miquel Raynal <miquel.raynal@bootlin.com>
To: Wang Zhaolong <wangzhaolong@huaweicloud.com>
Cc: richard@nod.at, vigneshr@ti.com, linux-mtd@lists.infradead.org,
yi.zhang@huawei.com, yangerkun@huawei.com,
chengzhihao1@huawei.com
Subject: Re: [bug report] mtd: bad block counter inflated when repeatedly marking the same block
Date: Mon, 01 Sep 2025 14:46:34 +0200 [thread overview]
Message-ID: <87y0qynxw5.fsf@bootlin.com> (raw)
In-Reply-To: <ef573188-9815-4a6b-bad1-3d8ff7c9b16f@huaweicloud.com> (Wang Zhaolong's message of "Mon, 1 Sep 2025 17:26:45 +0800")
Hello,
On 01/09/2025 at 17:26:45 +08, Wang Zhaolong <wangzhaolong@huaweicloud.com> wrote:
> Hi all,
>
> I’d like to report a mismatch between bad-block statistics and actual
> on-flash state when repeatedly calling MEMSETBADBLOCK on the same
> eraseblock.
>
> Summary
> - Repeatedly marking the same block bad (e.g., 5 times) makes
> /sys/class/mtd/mtdX/bad_blocks increase by 5.
> - After reboot, the statistical value ture to the correct value of 1.
> - So the runtime counter (ecc_stats.badblocks) is inflated.
>
> Repro (with nandsim.ko)
>
> ```bash
> # ID="0xec,0xa1,0x00,0x15" # 128M 128KB 2KB
> # modprobe nandsim id_bytes=$ID
> # ~/mtd-utils/mtd_markbad /dev/mtd1 10 1 # Repeat 5 times
> ......
> # ~/mtd-utils/mtd_markbad /dev/mtd1 10 1
>
> # -- It can be observed that 5 bad blocks will appear in the statistical information.
> # cat /sys/class/mtd/mtd1/bad_blocks
> 5
>
> # -- In fact, we can only scan 1 bad block.
> # ubiformat -v /dev/mtd1 | grep "bad eraseblock"
> ubiformat: 1 bad eraseblocks found, numbers: 10
> ```
>
> Root cause analysis (kernel-side)
>
> ```
> mtd_block_markbad
> mtd->_block_markbad()
> nand_block_markbad
> ret = nand_block_isbad
> return 0; // ret > 0
> mtd->ecc_stats.badblocks++; // No bad blocks was marked but was counted.
> Relevant code
> - drivers/mtd/nand/raw/nand_base.c:nand_block_markbad()
> - drivers/mtd/mtdcore.c:mtd_block_markbad()
> ```
>
> nand_block_markbad() returns 0 both for “newly marked” and “already bad”.
> mtdcore cannot tell whether this call actually added a new bad block,
> but still increments ecc_stats.badblocks.
>
> Possible fixes (high level)
> - Core-side conservative fix (minimal ABI change):
> * In mtd_block_markbad(), probe _block_isbad(master, ofs) before
> calling _block_markbad(), and (if available) probe again after
> success.
Sounds reasonable to me.
> * Only increment ecc_stats.badblocks if the state transitioned from
> “good” to “bad”.
>
> - Teach *_block_markbad() to return a distinct positive code for
> “already bad” vs “newly marked”, so the core can increment only on
> “newly marked”.
The subsystems have no other way to tell rather than probing the state
of the marker. I believe it is best to do it in mtd_block_markbad() in
the common mtdcore.c rather than in each implementation.
> What I want to know is:
> - Would the core-side pre/post _block_isbad check be acceptable as a short-term fix?
> - Any objections regarding the extra isbad IO in the markbad path?
Fine by me, it's not a hot path. If we end up here, we are already doing
damage control.;
> - Longer-term, is there interest in an explicit API/return-code semantics
> to differentiate “already bad” vs “newly marked”?
If you mean userspace API, I'd say not necessarily. Querying the stats
is probably the way to go. However in the kernel, while I would in
theory not be opposed to it, I don't see how one could implement that in
a more efficient way than probing the marker as discussed above in a
complex-free manner.
> I’m very interested in helping resolve this issue and would be grateful
> for any guidance or suggestions.
MTD folks in Cc, your feedback is also welcome ;-)
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
next prev parent reply other threads:[~2025-09-01 16:35 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-01 9:26 [bug report] mtd: bad block counter inflated when repeatedly marking the same block Wang Zhaolong
2025-09-01 12:40 ` Zhihao Cheng
2025-09-01 14:14 ` Wang Zhaolong
2025-09-01 12:46 ` Miquel Raynal [this message]
2025-09-01 14:16 ` Wang Zhaolong
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=87y0qynxw5.fsf@bootlin.com \
--to=miquel.raynal@bootlin.com \
--cc=chengzhihao1@huawei.com \
--cc=linux-mtd@lists.infradead.org \
--cc=richard@nod.at \
--cc=vigneshr@ti.com \
--cc=wangzhaolong@huaweicloud.com \
--cc=yangerkun@huawei.com \
--cc=yi.zhang@huawei.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.