Linux-mtd Archive on lore.kernel.org
 help / color / mirror / Atom feed
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/

  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox