* [PATCH 0/2] UBI: fix ubi.mtd MODULE_PARM_DESC issues and add per-device wear-leveling threshold @ 2026-07-23 2:02 ` Ran Hongyun 0 siblings, 0 replies; 18+ messages in thread From: Ran Hongyun @ 2026-07-23 2:02 UTC (permalink / raw) To: richard, miquel.raynal, vigneshr, vapier, artem.bityutskiy Cc: linux-mtd, linux-kernel, chengzhihao1, yangerkun, yi.zhang This series adds a per-device wear-leveling threshold for UBI devices, with a preparatory fix to the MODULE_PARM_DESC. Patch 1 fixes two pre-existing issues in the ubi.mtd MODULE_PARM_DESC: the parameter format string was missing the enable_fm and need_resv_pool tokens, and the bad-block reservation note was misplaced after Example 5 instead of after Example 3. Patch 2 extends struct ubi_attach_req with a __s32 wl_threshold field, plumbs it through the ioctl and module parameter paths, and replaces the compile-time macros UBI_WL_THRESHOLD and WL_FREE_MAX_DIFF with p er-device fields across wl.c and fastmap-wl.c. 0 means "use the kernel default", the accepted range is 2-65536. Ran Hongyun (2): UBI: fix two issues in the ubi.mtd MODULE_PARM_DESC UBI: support per-device wear-leveling threshold drivers/mtd/ubi/build.c | 43 ++++++++++++++++++++++++++++++------ drivers/mtd/ubi/cdev.c | 2 +- drivers/mtd/ubi/fastmap-wl.c | 8 +++---- drivers/mtd/ubi/ubi.h | 21 +++++++++++++++++- drivers/mtd/ubi/wl.c | 39 ++++++++------------------------ include/uapi/mtd/ubi-user.h | 10 ++++++++- 6 files changed, 79 insertions(+), 44 deletions(-) -- 2.52.0 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 0/2] UBI: fix ubi.mtd MODULE_PARM_DESC issues and add per-device wear-leveling threshold @ 2026-07-23 2:02 ` Ran Hongyun 0 siblings, 0 replies; 18+ messages in thread From: Ran Hongyun @ 2026-07-23 2:02 UTC (permalink / raw) To: richard, miquel.raynal, vigneshr, vapier, artem.bityutskiy Cc: linux-mtd, linux-kernel, chengzhihao1, yangerkun, yi.zhang This series adds a per-device wear-leveling threshold for UBI devices, with a preparatory fix to the MODULE_PARM_DESC. Patch 1 fixes two pre-existing issues in the ubi.mtd MODULE_PARM_DESC: the parameter format string was missing the enable_fm and need_resv_pool tokens, and the bad-block reservation note was misplaced after Example 5 instead of after Example 3. Patch 2 extends struct ubi_attach_req with a __s32 wl_threshold field, plumbs it through the ioctl and module parameter paths, and replaces the compile-time macros UBI_WL_THRESHOLD and WL_FREE_MAX_DIFF with p er-device fields across wl.c and fastmap-wl.c. 0 means "use the kernel default", the accepted range is 2-65536. Ran Hongyun (2): UBI: fix two issues in the ubi.mtd MODULE_PARM_DESC UBI: support per-device wear-leveling threshold drivers/mtd/ubi/build.c | 43 ++++++++++++++++++++++++++++++------ drivers/mtd/ubi/cdev.c | 2 +- drivers/mtd/ubi/fastmap-wl.c | 8 +++---- drivers/mtd/ubi/ubi.h | 21 +++++++++++++++++- drivers/mtd/ubi/wl.c | 39 ++++++++------------------------ include/uapi/mtd/ubi-user.h | 10 ++++++++- 6 files changed, 79 insertions(+), 44 deletions(-) -- 2.52.0 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/2] UBI: fix two issues in the ubi.mtd MODULE_PARM_DESC 2026-07-23 2:02 ` Ran Hongyun @ 2026-07-23 2:02 ` Ran Hongyun -1 siblings, 0 replies; 18+ messages in thread From: Ran Hongyun @ 2026-07-23 2:02 UTC (permalink / raw) To: richard, miquel.raynal, vigneshr, vapier, artem.bityutskiy Cc: linux-mtd, linux-kernel, chengzhihao1, yangerkun, yi.zhang Fix two issues introduced before: - The parameter format string was missing the enable_fm and need_resv_pool tokens introduced in an earlier commit. - The bad-block reservation note was misplaced after Example 5 instead of after Example 3. It was misplaced due to an earlier patch. Fixes: 83ff59a06663 ("UBI: support ubi_num on mtd.ubi command line") Signed-off-by: Ran Hongyun <ranhongyun1@huawei.com> --- drivers/mtd/ubi/build.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 674ad87809df..8e5f178168cb 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1574,7 +1574,7 @@ static int ubi_mtd_param_parse(const char *val, const struct kernel_param *kp) } module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 0400); -MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num]]].\n" +MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num[,enable_fm[,need_resv_pool]]]]].\n" "Multiple \"mtd\" parameters may be specified.\n" "MTD devices may be specified by their number, name, or path to the MTD character device node.\n" "Optional \"vid_hdr_offs\" parameter specifies UBI VID header position to be used by UBI. (default value if 0)\n" @@ -1587,9 +1587,9 @@ MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|pa "Example 1: mtd=/dev/mtd0 - attach MTD device /dev/mtd0.\n" "Example 2: mtd=content,1984 mtd=4 - attach MTD device with name \"content\" using VID header offset 1984, and MTD device number 4 with default VID header offset.\n" "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n" + "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device).\n" "Example 4: mtd=/dev/mtd1,0,0,5 - attach MTD device /dev/mtd1 to UBI 5 and using default values for the other fields.\n" - "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n" - "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device)."); + "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n"); #ifdef CONFIG_MTD_UBI_FASTMAP module_param(fm_autoconvert, bool, 0644); MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap."); -- 2.52.0 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 1/2] UBI: fix two issues in the ubi.mtd MODULE_PARM_DESC @ 2026-07-23 2:02 ` Ran Hongyun 0 siblings, 0 replies; 18+ messages in thread From: Ran Hongyun @ 2026-07-23 2:02 UTC (permalink / raw) To: richard, miquel.raynal, vigneshr, vapier, artem.bityutskiy Cc: linux-mtd, linux-kernel, chengzhihao1, yangerkun, yi.zhang Fix two issues introduced before: - The parameter format string was missing the enable_fm and need_resv_pool tokens introduced in an earlier commit. - The bad-block reservation note was misplaced after Example 5 instead of after Example 3. It was misplaced due to an earlier patch. Fixes: 83ff59a06663 ("UBI: support ubi_num on mtd.ubi command line") Signed-off-by: Ran Hongyun <ranhongyun1@huawei.com> --- drivers/mtd/ubi/build.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 674ad87809df..8e5f178168cb 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1574,7 +1574,7 @@ static int ubi_mtd_param_parse(const char *val, const struct kernel_param *kp) } module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 0400); -MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num]]].\n" +MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num[,enable_fm[,need_resv_pool]]]]].\n" "Multiple \"mtd\" parameters may be specified.\n" "MTD devices may be specified by their number, name, or path to the MTD character device node.\n" "Optional \"vid_hdr_offs\" parameter specifies UBI VID header position to be used by UBI. (default value if 0)\n" @@ -1587,9 +1587,9 @@ MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|pa "Example 1: mtd=/dev/mtd0 - attach MTD device /dev/mtd0.\n" "Example 2: mtd=content,1984 mtd=4 - attach MTD device with name \"content\" using VID header offset 1984, and MTD device number 4 with default VID header offset.\n" "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n" + "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device).\n" "Example 4: mtd=/dev/mtd1,0,0,5 - attach MTD device /dev/mtd1 to UBI 5 and using default values for the other fields.\n" - "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n" - "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device)."); + "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n"); #ifdef CONFIG_MTD_UBI_FASTMAP module_param(fm_autoconvert, bool, 0644); MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap."); -- 2.52.0 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 1/2] UBI: fix two issues in the ubi.mtd MODULE_PARM_DESC 2026-07-23 2:02 ` Ran Hongyun @ 2026-07-23 2:40 ` Zhihao Cheng -1 siblings, 0 replies; 18+ messages in thread From: Zhihao Cheng @ 2026-07-23 2:40 UTC (permalink / raw) To: Ran Hongyun, richard, miquel.raynal, vigneshr, vapier, artem.bityutskiy Cc: linux-mtd, linux-kernel, yangerkun, yi.zhang 在 2026/7/23 10:02, Ran Hongyun 写道: > Fix two issues introduced before: > > - The parameter format string was missing the enable_fm and > need_resv_pool tokens introduced in an earlier commit. > > - The bad-block reservation note was misplaced after Example 5 > instead of after Example 3. It was misplaced due to an earlier patch. > > Fixes: 83ff59a06663 ("UBI: support ubi_num on mtd.ubi command line") > Signed-off-by: Ran Hongyun <ranhongyun1@huawei.com> > --- > drivers/mtd/ubi/build.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com> > diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c > index 674ad87809df..8e5f178168cb 100644 > --- a/drivers/mtd/ubi/build.c > +++ b/drivers/mtd/ubi/build.c > @@ -1574,7 +1574,7 @@ static int ubi_mtd_param_parse(const char *val, const struct kernel_param *kp) > } > > module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 0400); > -MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num]]].\n" > +MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num[,enable_fm[,need_resv_pool]]]]].\n" > "Multiple \"mtd\" parameters may be specified.\n" > "MTD devices may be specified by their number, name, or path to the MTD character device node.\n" > "Optional \"vid_hdr_offs\" parameter specifies UBI VID header position to be used by UBI. (default value if 0)\n" > @@ -1587,9 +1587,9 @@ MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|pa > "Example 1: mtd=/dev/mtd0 - attach MTD device /dev/mtd0.\n" > "Example 2: mtd=content,1984 mtd=4 - attach MTD device with name \"content\" using VID header offset 1984, and MTD device number 4 with default VID header offset.\n" > "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n" > + "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device).\n" > "Example 4: mtd=/dev/mtd1,0,0,5 - attach MTD device /dev/mtd1 to UBI 5 and using default values for the other fields.\n" > - "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n" > - "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device)."); > + "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n"); > #ifdef CONFIG_MTD_UBI_FASTMAP > module_param(fm_autoconvert, bool, 0644); > MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap."); > ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/2] UBI: fix two issues in the ubi.mtd MODULE_PARM_DESC @ 2026-07-23 2:40 ` Zhihao Cheng 0 siblings, 0 replies; 18+ messages in thread From: Zhihao Cheng @ 2026-07-23 2:40 UTC (permalink / raw) To: Ran Hongyun, richard, miquel.raynal, vigneshr, vapier, artem.bityutskiy Cc: linux-mtd, linux-kernel, yangerkun, yi.zhang 在 2026/7/23 10:02, Ran Hongyun 写道: > Fix two issues introduced before: > > - The parameter format string was missing the enable_fm and > need_resv_pool tokens introduced in an earlier commit. > > - The bad-block reservation note was misplaced after Example 5 > instead of after Example 3. It was misplaced due to an earlier patch. > > Fixes: 83ff59a06663 ("UBI: support ubi_num on mtd.ubi command line") > Signed-off-by: Ran Hongyun <ranhongyun1@huawei.com> > --- > drivers/mtd/ubi/build.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com> > diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c > index 674ad87809df..8e5f178168cb 100644 > --- a/drivers/mtd/ubi/build.c > +++ b/drivers/mtd/ubi/build.c > @@ -1574,7 +1574,7 @@ static int ubi_mtd_param_parse(const char *val, const struct kernel_param *kp) > } > > module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 0400); > -MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num]]].\n" > +MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num[,enable_fm[,need_resv_pool]]]]].\n" > "Multiple \"mtd\" parameters may be specified.\n" > "MTD devices may be specified by their number, name, or path to the MTD character device node.\n" > "Optional \"vid_hdr_offs\" parameter specifies UBI VID header position to be used by UBI. (default value if 0)\n" > @@ -1587,9 +1587,9 @@ MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|pa > "Example 1: mtd=/dev/mtd0 - attach MTD device /dev/mtd0.\n" > "Example 2: mtd=content,1984 mtd=4 - attach MTD device with name \"content\" using VID header offset 1984, and MTD device number 4 with default VID header offset.\n" > "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n" > + "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device).\n" > "Example 4: mtd=/dev/mtd1,0,0,5 - attach MTD device /dev/mtd1 to UBI 5 and using default values for the other fields.\n" > - "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n" > - "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device)."); > + "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n"); > #ifdef CONFIG_MTD_UBI_FASTMAP > module_param(fm_autoconvert, bool, 0644); > MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap."); > ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 2/2] UBI: support per-device wear-leveling threshold 2026-07-23 2:02 ` Ran Hongyun @ 2026-07-23 2:02 ` Ran Hongyun -1 siblings, 0 replies; 18+ messages in thread From: Ran Hongyun @ 2026-07-23 2:02 UTC (permalink / raw) To: richard, miquel.raynal, vigneshr, vapier, artem.bityutskiy Cc: linux-mtd, linux-kernel, chengzhihao1, yangerkun, yi.zhang The UBI wear-leveling threshold (CONFIG_MTD_UBI_WL_THRESHOLD) is currently a compile-time constant shared by all UBI devices. When a single kernel image must support multiple NAND flashes with different erase lifetimes, one global threshold cannot suit all devices. Add a per-device configurable wl_threshold parameter: - UAPI: add __s32 wl_threshold to struct ubi_attach_req, carved from the existing padding. - Module parameter: ubi.mtd gains a new optional token "wl_threshold": ubi.mtd=0,0,0,0,0,0,256 ubi.mtd=1,0,0,0,0,0,4096 0 means "use the kernel default", the accepted range is 2-65536. Signed-off-by: Ran Hongyun <ranhongyun1@huawei.com> --- drivers/mtd/ubi/build.c | 43 ++++++++++++++++++++++++++++++------ drivers/mtd/ubi/cdev.c | 2 +- drivers/mtd/ubi/fastmap-wl.c | 8 +++---- drivers/mtd/ubi/ubi.h | 21 +++++++++++++++++- drivers/mtd/ubi/wl.c | 39 ++++++++------------------------ include/uapi/mtd/ubi-user.h | 10 ++++++++- 6 files changed, 79 insertions(+), 44 deletions(-) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 8e5f178168cb..ed0216f70220 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -36,7 +36,7 @@ #define MTD_PARAM_LEN_MAX 64 /* Maximum number of comma-separated items in the 'mtd=' parameter */ -#define MTD_PARAM_MAX_COUNT 6 +#define MTD_PARAM_MAX_COUNT 7 /* Maximum value for the number of bad PEBs per 1024 PEBs */ #define MAX_MTD_UBI_BEB_LIMIT 768 @@ -56,6 +56,7 @@ * @max_beb_per1024: maximum expected number of bad PEBs per 1024 PEBs * @enable_fm: enable fastmap when value is non-zero * @need_resv_pool: reserve pool->max_size pebs when value is none-zero + * @wl_threshold: wear-leveling threshold, 0 means use CONFIG_MTD_UBI_WL_THRESHOLD */ struct mtd_dev_param { char name[MTD_PARAM_LEN_MAX]; @@ -64,6 +65,7 @@ struct mtd_dev_param { int max_beb_per1024; int enable_fm; int need_resv_pool; + int wl_threshold; }; /* Numbers of elements set in the @mtd_dev_param array */ @@ -832,6 +834,8 @@ static int autoresize(struct ubi_device *ubi, int vol_id) * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs * @disable_fm: whether disable fastmap * @need_resv_pool: whether reserve pebs to fill fm_pool + * @wl_threshold: wear-leveling threshold for this UBI device; 0 means use + * %CONFIG_MTD_UBI_WL_THRESHOLD; accepted range is 2-65536 * * This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number * to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in @@ -848,7 +852,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) */ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset, int max_beb_per1024, bool disable_fm, - bool need_resv_pool) + bool need_resv_pool, int wl_threshold) { struct ubi_device *ubi; int i, err; @@ -859,6 +863,15 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, if (!max_beb_per1024) max_beb_per1024 = CONFIG_MTD_UBI_BEB_LIMIT; + if (!wl_threshold) + wl_threshold = CONFIG_MTD_UBI_WL_THRESHOLD; + + if (wl_threshold < 2 || wl_threshold > 65536) { + pr_err("ubi: bad wear-leveling threshold %d\n", + wl_threshold); + return -EINVAL; + } + /* * Check if we already have the same MTD device attached. * @@ -944,6 +957,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ubi->ubi_num = ubi_num; ubi->vid_hdr_offset = vid_hdr_offset; ubi->autoresize_vol_id = -1; + ubi->wl_threshold = wl_threshold; + ubi->wl_free_max_diff = wl_threshold * 2; #ifdef CONFIG_MTD_UBI_FASTMAP ubi->fm_pool.used = ubi->fm_pool.size = 0; @@ -1044,7 +1059,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ubi->vol_count - UBI_INT_VOL_COUNT, UBI_INT_VOL_COUNT, ubi->vtbl_slots); ubi_msg(ubi, "max/mean erase counter: %d/%d, WL threshold: %d, image sequence number: %u", - ubi->max_ec, ubi->mean_ec, CONFIG_MTD_UBI_WL_THRESHOLD, + ubi->max_ec, ubi->mean_ec, ubi->wl_threshold, ubi->image_seq); ubi_msg(ubi, "available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d", ubi->avail_pebs, ubi->rsvd_pebs, ubi->beb_rsvd_pebs); @@ -1247,7 +1262,7 @@ static void ubi_notify_add(struct mtd_info *mtd) /* called while holding mtd_table_mutex */ mutex_lock_nested(&ubi_devices_mutex, SINGLE_DEPTH_NESTING); - err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false, false); + err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false, false, 0); mutex_unlock(&ubi_devices_mutex); if (err < 0) __put_mtd_device(mtd); @@ -1289,7 +1304,8 @@ static int __init ubi_init_attach(void) err = ubi_attach_mtd_dev(mtd, p->ubi_num, p->vid_hdr_offs, p->max_beb_per1024, p->enable_fm == 0, - p->need_resv_pool != 0); + p->need_resv_pool != 0, + p->wl_threshold); mutex_unlock(&ubi_devices_mutex); if (err < 0) { pr_err("UBI error: cannot attach mtd%d\n", @@ -1569,12 +1585,24 @@ static int ubi_mtd_param_parse(const char *val, const struct kernel_param *kp) } else p->need_resv_pool = 0; + token = tokens[6]; + if (token) { + int err = kstrtoint(token, 10, &p->wl_threshold); + + if (err) { + pr_err("UBI error: bad value for wl_threshold parameter: %s\n", + token); + return -EINVAL; + } + } else + p->wl_threshold = 0; + mtd_devs += 1; return 0; } module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 0400); -MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num[,enable_fm[,need_resv_pool]]]]].\n" +MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num[,enable_fm[,need_resv_pool[,wl_threshold]]]]]].\n" "Multiple \"mtd\" parameters may be specified.\n" "MTD devices may be specified by their number, name, or path to the MTD character device node.\n" "Optional \"vid_hdr_offs\" parameter specifies UBI VID header position to be used by UBI. (default value if 0)\n" @@ -1589,7 +1617,8 @@ MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|pa "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n" "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device).\n" "Example 4: mtd=/dev/mtd1,0,0,5 - attach MTD device /dev/mtd1 to UBI 5 and using default values for the other fields.\n" - "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n"); + "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n" + "Example 6: mtd=/dev/mtd0,0,0,0,0,0,256 mtd=/dev/mtd1,0,0,0,0,0,4096 - attach MTD device /dev/mtd0 with wear-leveling threshold 256, and MTD device /dev/mtd1 with threshold 4096.\n"); #ifdef CONFIG_MTD_UBI_FASTMAP module_param(fm_autoconvert, bool, 0644); MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap."); diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index fd39030dbf89..54acd8394d67 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -1112,7 +1112,7 @@ static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, mutex_lock(&ubi_devices_mutex); err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset, req.max_beb_per1024, !!req.disable_fm, - !!req.need_resv_pool); + !!req.need_resv_pool, req.wl_threshold); mutex_unlock(&ubi_devices_mutex); if (err < 0) put_mtd_device(mtd); diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c index a0f750411f9d..e24bb6b18e90 100644 --- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -238,7 +238,7 @@ void ubi_refill_pools_and_lock(struct ubi_device *ubi) if (left_free <= 0) break; - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF, + e = find_wl_entry(ubi, &ubi->free, ubi->wl_free_max_diff, !can_fill_pools(ubi, left_free)); self_check_in_wl_tree(ubi, e, &ubi->free); rb_erase(&e->u.rb, &ubi->free); @@ -392,18 +392,18 @@ static bool need_wear_leveling(struct ubi_device *ubi) if (!e) { if (!ubi->free.rb_node) return false; - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF, 0); + e = find_wl_entry(ubi, &ubi->free, ubi->wl_free_max_diff, 0); ec = e->ec; } else { ec = e->ec; if (ubi->free.rb_node) { - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF, 0); + e = find_wl_entry(ubi, &ubi->free, ubi->wl_free_max_diff, 0); ec = max(ec, e->ec); } } e = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); - return ec - e->ec >= UBI_WL_THRESHOLD; + return ec - e->ec >= ubi->wl_threshold; } /* get_peb_for_wl - returns a PEB to be used internally by the WL sub-system. diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index af466cd83ae0..62026931d05e 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -516,6 +516,22 @@ struct ubi_debug_info { * @bgt_thread: background thread description object * @thread_enabled: if the background thread is enabled * @bgt_name: background thread name + * @wl_threshold: Maximum difference between two erase counters. If this + * threshold is exceeded, the WL sub-system starts moving + * data from used physical eraseblocks with low erase + * counter to free physical eraseblocks with high erase counter. + * @wl_free_max_diff: When a physical eraseblock is moved, the WL sub-system + * has to pick the target physical eraseblock to move to. + * The simplest way would be just to pick the one with the + * highest erase counter. But in certain workloads this + * could lead to an unlimited wear of one or few physical + * eraseblock. Indeed, imagine a situation when the picked + * physical eraseblock is constantly erased after the + * data is written to it. So, we have a constant which + * limits the highest erase counter of the free physical + * eraseblock to pick. Namely, the WL sub-system does not + * pick eraseblocks with erase counter greater than the + * lowest erase counter plus @wl_free_max_diff. * * @flash_size: underlying MTD device size (in bytes) * @peb_count: count of physical eraseblocks on the MTD device @@ -623,6 +639,8 @@ struct ubi_device { struct task_struct *bgt_thread; int thread_enabled; char bgt_name[sizeof(UBI_BGT_NAME_PATTERN)+2]; + int wl_threshold; + int wl_free_max_diff; /* I/O sub-system's stuff */ long long flash_size; @@ -938,7 +956,8 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, /* build.c */ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset, int max_beb_per1024, - bool disable_fm, bool need_resv_pool); + bool disable_fm, bool need_resv_pool, + int wl_threshold); int ubi_detach_mtd_dev(int ubi_num, int anyway); struct ubi_device *ubi_get_device(int ubi_num); void ubi_put_device(struct ubi_device *ubi); diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index e3705db8e570..4e18044a20c0 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -95,27 +95,6 @@ /* Number of physical eraseblocks reserved for wear-leveling purposes */ #define WL_RESERVED_PEBS 1 -/* - * Maximum difference between two erase counters. If this threshold is - * exceeded, the WL sub-system starts moving data from used physical - * eraseblocks with low erase counter to free physical eraseblocks with high - * erase counter. - */ -#define UBI_WL_THRESHOLD CONFIG_MTD_UBI_WL_THRESHOLD - -/* - * When a physical eraseblock is moved, the WL sub-system has to pick the target - * physical eraseblock to move to. The simplest way would be just to pick the - * one with the highest erase counter. But in certain workloads this could lead - * to an unlimited wear of one or few physical eraseblock. Indeed, imagine a - * situation when the picked physical eraseblock is constantly erased after the - * data is written to it. So, we have a constant which limits the highest erase - * counter of the free physical eraseblock to pick. Namely, the WL sub-system - * does not pick eraseblocks with erase counter greater than the lowest erase - * counter plus %WL_FREE_MAX_DIFF. - */ -#define WL_FREE_MAX_DIFF (2*UBI_WL_THRESHOLD) - /* * Maximum number of consecutive background thread failures which is enough to * switch to read-only mode. @@ -358,7 +337,7 @@ static struct ubi_wl_entry *find_wl_entry(struct ubi_device *ubi, * * This function looks for a wear leveling entry with medium erase counter, * but not greater or equivalent than the lowest erase counter plus - * %WL_FREE_MAX_DIFF/2. + * @ubi->wl_free_max_diff/2. */ static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi, struct rb_root *root) @@ -368,7 +347,7 @@ static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi, first = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); last = rb_entry(rb_last(root), struct ubi_wl_entry, u.rb); - if (last->ec - first->ec < WL_FREE_MAX_DIFF) { + if (last->ec - first->ec < ubi->wl_free_max_diff) { e = rb_entry(root->rb_node, struct ubi_wl_entry, u.rb); /* @@ -379,7 +358,7 @@ static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi, */ e = may_reserve_for_fm(ubi, e, root); } else - e = find_wl_entry(ubi, root, WL_FREE_MAX_DIFF/2, 0); + e = find_wl_entry(ubi, root, ubi->wl_free_max_diff/2, 0); return e; } @@ -706,7 +685,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, #ifdef CONFIG_MTD_UBI_FASTMAP e1 = find_anchor_wl_entry(&ubi->used); if (e1 && ubi->fm_anchor && - (ubi->fm_anchor->ec - e1->ec >= UBI_WL_THRESHOLD)) { + (ubi->fm_anchor->ec - e1->ec >= ubi->wl_threshold)) { ubi->fm_do_produce_anchor = 1; /* * fm_anchor is no longer considered a good anchor. @@ -743,7 +722,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, if (!e2) goto out_cancel; - if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) { + if (!(e2->ec - e1->ec >= ubi->wl_threshold)) { dbg_wl("no WL needed: min used EC %d, max free EC %d", e1->ec, e2->ec); @@ -1056,12 +1035,12 @@ static int ensure_wear_leveling(struct ubi_device *ubi, int nested) * We schedule wear-leveling only if the difference between the * lowest erase counter of used physical eraseblocks and a high * erase counter of free physical eraseblocks is greater than - * %UBI_WL_THRESHOLD. + * @ubi->wl_threshold. */ e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); - e2 = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF, 0); + e2 = find_wl_entry(ubi, &ubi->free, ubi->wl_free_max_diff, 0); - if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) + if (!(e2->ec - e1->ec >= ubi->wl_threshold)) goto out_unlock; #endif dbg_wl("schedule wear-leveling"); @@ -2090,7 +2069,7 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) { struct ubi_wl_entry *e; - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF, 0); + e = find_wl_entry(ubi, &ubi->free, ubi->wl_free_max_diff, 0); self_check_in_wl_tree(ubi, e, &ubi->free); ubi->free_count--; ubi_assert(ubi->free_count >= 0); diff --git a/include/uapi/mtd/ubi-user.h b/include/uapi/mtd/ubi-user.h index aa872a41ffb9..3538e11b5175 100644 --- a/include/uapi/mtd/ubi-user.h +++ b/include/uapi/mtd/ubi-user.h @@ -289,6 +289,13 @@ enum { * If @disable_fm is not zero, ubi doesn't create new fastmap even the module * param 'fm_autoconvert' is set, and existed old fastmap will be destroyed * after doing full scanning. + * + * The @wl_threshold defines the maximum difference between the highest and the + * lowest erase counter value of eraseblocks of this UBI device. When this + * threshold is exceeded, UBI starts performing wear leveling by means of + * moving data from eraseblock with low erase counter to eraseblocks with high + * erase counter. If @wl_threshold is zero, the default kernel value of + * %CONFIG_MTD_UBI_WL_THRESHOLD is used. The accepted range is 2-65536. */ struct ubi_attach_req { __s32 ubi_num; @@ -297,7 +304,8 @@ struct ubi_attach_req { __s16 max_beb_per1024; __s8 disable_fm; __s8 need_resv_pool; - __s8 padding[8]; + __s32 wl_threshold; + __s8 padding[4]; }; /* -- 2.52.0 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 2/2] UBI: support per-device wear-leveling threshold @ 2026-07-23 2:02 ` Ran Hongyun 0 siblings, 0 replies; 18+ messages in thread From: Ran Hongyun @ 2026-07-23 2:02 UTC (permalink / raw) To: richard, miquel.raynal, vigneshr, vapier, artem.bityutskiy Cc: linux-mtd, linux-kernel, chengzhihao1, yangerkun, yi.zhang The UBI wear-leveling threshold (CONFIG_MTD_UBI_WL_THRESHOLD) is currently a compile-time constant shared by all UBI devices. When a single kernel image must support multiple NAND flashes with different erase lifetimes, one global threshold cannot suit all devices. Add a per-device configurable wl_threshold parameter: - UAPI: add __s32 wl_threshold to struct ubi_attach_req, carved from the existing padding. - Module parameter: ubi.mtd gains a new optional token "wl_threshold": ubi.mtd=0,0,0,0,0,0,256 ubi.mtd=1,0,0,0,0,0,4096 0 means "use the kernel default", the accepted range is 2-65536. Signed-off-by: Ran Hongyun <ranhongyun1@huawei.com> --- drivers/mtd/ubi/build.c | 43 ++++++++++++++++++++++++++++++------ drivers/mtd/ubi/cdev.c | 2 +- drivers/mtd/ubi/fastmap-wl.c | 8 +++---- drivers/mtd/ubi/ubi.h | 21 +++++++++++++++++- drivers/mtd/ubi/wl.c | 39 ++++++++------------------------ include/uapi/mtd/ubi-user.h | 10 ++++++++- 6 files changed, 79 insertions(+), 44 deletions(-) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 8e5f178168cb..ed0216f70220 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -36,7 +36,7 @@ #define MTD_PARAM_LEN_MAX 64 /* Maximum number of comma-separated items in the 'mtd=' parameter */ -#define MTD_PARAM_MAX_COUNT 6 +#define MTD_PARAM_MAX_COUNT 7 /* Maximum value for the number of bad PEBs per 1024 PEBs */ #define MAX_MTD_UBI_BEB_LIMIT 768 @@ -56,6 +56,7 @@ * @max_beb_per1024: maximum expected number of bad PEBs per 1024 PEBs * @enable_fm: enable fastmap when value is non-zero * @need_resv_pool: reserve pool->max_size pebs when value is none-zero + * @wl_threshold: wear-leveling threshold, 0 means use CONFIG_MTD_UBI_WL_THRESHOLD */ struct mtd_dev_param { char name[MTD_PARAM_LEN_MAX]; @@ -64,6 +65,7 @@ struct mtd_dev_param { int max_beb_per1024; int enable_fm; int need_resv_pool; + int wl_threshold; }; /* Numbers of elements set in the @mtd_dev_param array */ @@ -832,6 +834,8 @@ static int autoresize(struct ubi_device *ubi, int vol_id) * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs * @disable_fm: whether disable fastmap * @need_resv_pool: whether reserve pebs to fill fm_pool + * @wl_threshold: wear-leveling threshold for this UBI device; 0 means use + * %CONFIG_MTD_UBI_WL_THRESHOLD; accepted range is 2-65536 * * This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number * to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in @@ -848,7 +852,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) */ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset, int max_beb_per1024, bool disable_fm, - bool need_resv_pool) + bool need_resv_pool, int wl_threshold) { struct ubi_device *ubi; int i, err; @@ -859,6 +863,15 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, if (!max_beb_per1024) max_beb_per1024 = CONFIG_MTD_UBI_BEB_LIMIT; + if (!wl_threshold) + wl_threshold = CONFIG_MTD_UBI_WL_THRESHOLD; + + if (wl_threshold < 2 || wl_threshold > 65536) { + pr_err("ubi: bad wear-leveling threshold %d\n", + wl_threshold); + return -EINVAL; + } + /* * Check if we already have the same MTD device attached. * @@ -944,6 +957,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ubi->ubi_num = ubi_num; ubi->vid_hdr_offset = vid_hdr_offset; ubi->autoresize_vol_id = -1; + ubi->wl_threshold = wl_threshold; + ubi->wl_free_max_diff = wl_threshold * 2; #ifdef CONFIG_MTD_UBI_FASTMAP ubi->fm_pool.used = ubi->fm_pool.size = 0; @@ -1044,7 +1059,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ubi->vol_count - UBI_INT_VOL_COUNT, UBI_INT_VOL_COUNT, ubi->vtbl_slots); ubi_msg(ubi, "max/mean erase counter: %d/%d, WL threshold: %d, image sequence number: %u", - ubi->max_ec, ubi->mean_ec, CONFIG_MTD_UBI_WL_THRESHOLD, + ubi->max_ec, ubi->mean_ec, ubi->wl_threshold, ubi->image_seq); ubi_msg(ubi, "available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d", ubi->avail_pebs, ubi->rsvd_pebs, ubi->beb_rsvd_pebs); @@ -1247,7 +1262,7 @@ static void ubi_notify_add(struct mtd_info *mtd) /* called while holding mtd_table_mutex */ mutex_lock_nested(&ubi_devices_mutex, SINGLE_DEPTH_NESTING); - err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false, false); + err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false, false, 0); mutex_unlock(&ubi_devices_mutex); if (err < 0) __put_mtd_device(mtd); @@ -1289,7 +1304,8 @@ static int __init ubi_init_attach(void) err = ubi_attach_mtd_dev(mtd, p->ubi_num, p->vid_hdr_offs, p->max_beb_per1024, p->enable_fm == 0, - p->need_resv_pool != 0); + p->need_resv_pool != 0, + p->wl_threshold); mutex_unlock(&ubi_devices_mutex); if (err < 0) { pr_err("UBI error: cannot attach mtd%d\n", @@ -1569,12 +1585,24 @@ static int ubi_mtd_param_parse(const char *val, const struct kernel_param *kp) } else p->need_resv_pool = 0; + token = tokens[6]; + if (token) { + int err = kstrtoint(token, 10, &p->wl_threshold); + + if (err) { + pr_err("UBI error: bad value for wl_threshold parameter: %s\n", + token); + return -EINVAL; + } + } else + p->wl_threshold = 0; + mtd_devs += 1; return 0; } module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 0400); -MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num[,enable_fm[,need_resv_pool]]]]].\n" +MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num[,enable_fm[,need_resv_pool[,wl_threshold]]]]]].\n" "Multiple \"mtd\" parameters may be specified.\n" "MTD devices may be specified by their number, name, or path to the MTD character device node.\n" "Optional \"vid_hdr_offs\" parameter specifies UBI VID header position to be used by UBI. (default value if 0)\n" @@ -1589,7 +1617,8 @@ MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|pa "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n" "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device).\n" "Example 4: mtd=/dev/mtd1,0,0,5 - attach MTD device /dev/mtd1 to UBI 5 and using default values for the other fields.\n" - "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n"); + "example 5: mtd=1,0,0,5 mtd=2,0,0,6,1 - attach MTD device /dev/mtd1 to UBI 5 and disable fastmap; attach MTD device /dev/mtd2 to UBI 6 and enable fastmap.(only works when fastmap is enabled and fm_autoconvert=Y).\n" + "Example 6: mtd=/dev/mtd0,0,0,0,0,0,256 mtd=/dev/mtd1,0,0,0,0,0,4096 - attach MTD device /dev/mtd0 with wear-leveling threshold 256, and MTD device /dev/mtd1 with threshold 4096.\n"); #ifdef CONFIG_MTD_UBI_FASTMAP module_param(fm_autoconvert, bool, 0644); MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap."); diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index fd39030dbf89..54acd8394d67 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -1112,7 +1112,7 @@ static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, mutex_lock(&ubi_devices_mutex); err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset, req.max_beb_per1024, !!req.disable_fm, - !!req.need_resv_pool); + !!req.need_resv_pool, req.wl_threshold); mutex_unlock(&ubi_devices_mutex); if (err < 0) put_mtd_device(mtd); diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c index a0f750411f9d..e24bb6b18e90 100644 --- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -238,7 +238,7 @@ void ubi_refill_pools_and_lock(struct ubi_device *ubi) if (left_free <= 0) break; - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF, + e = find_wl_entry(ubi, &ubi->free, ubi->wl_free_max_diff, !can_fill_pools(ubi, left_free)); self_check_in_wl_tree(ubi, e, &ubi->free); rb_erase(&e->u.rb, &ubi->free); @@ -392,18 +392,18 @@ static bool need_wear_leveling(struct ubi_device *ubi) if (!e) { if (!ubi->free.rb_node) return false; - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF, 0); + e = find_wl_entry(ubi, &ubi->free, ubi->wl_free_max_diff, 0); ec = e->ec; } else { ec = e->ec; if (ubi->free.rb_node) { - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF, 0); + e = find_wl_entry(ubi, &ubi->free, ubi->wl_free_max_diff, 0); ec = max(ec, e->ec); } } e = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); - return ec - e->ec >= UBI_WL_THRESHOLD; + return ec - e->ec >= ubi->wl_threshold; } /* get_peb_for_wl - returns a PEB to be used internally by the WL sub-system. diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index af466cd83ae0..62026931d05e 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -516,6 +516,22 @@ struct ubi_debug_info { * @bgt_thread: background thread description object * @thread_enabled: if the background thread is enabled * @bgt_name: background thread name + * @wl_threshold: Maximum difference between two erase counters. If this + * threshold is exceeded, the WL sub-system starts moving + * data from used physical eraseblocks with low erase + * counter to free physical eraseblocks with high erase counter. + * @wl_free_max_diff: When a physical eraseblock is moved, the WL sub-system + * has to pick the target physical eraseblock to move to. + * The simplest way would be just to pick the one with the + * highest erase counter. But in certain workloads this + * could lead to an unlimited wear of one or few physical + * eraseblock. Indeed, imagine a situation when the picked + * physical eraseblock is constantly erased after the + * data is written to it. So, we have a constant which + * limits the highest erase counter of the free physical + * eraseblock to pick. Namely, the WL sub-system does not + * pick eraseblocks with erase counter greater than the + * lowest erase counter plus @wl_free_max_diff. * * @flash_size: underlying MTD device size (in bytes) * @peb_count: count of physical eraseblocks on the MTD device @@ -623,6 +639,8 @@ struct ubi_device { struct task_struct *bgt_thread; int thread_enabled; char bgt_name[sizeof(UBI_BGT_NAME_PATTERN)+2]; + int wl_threshold; + int wl_free_max_diff; /* I/O sub-system's stuff */ long long flash_size; @@ -938,7 +956,8 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, /* build.c */ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset, int max_beb_per1024, - bool disable_fm, bool need_resv_pool); + bool disable_fm, bool need_resv_pool, + int wl_threshold); int ubi_detach_mtd_dev(int ubi_num, int anyway); struct ubi_device *ubi_get_device(int ubi_num); void ubi_put_device(struct ubi_device *ubi); diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index e3705db8e570..4e18044a20c0 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -95,27 +95,6 @@ /* Number of physical eraseblocks reserved for wear-leveling purposes */ #define WL_RESERVED_PEBS 1 -/* - * Maximum difference between two erase counters. If this threshold is - * exceeded, the WL sub-system starts moving data from used physical - * eraseblocks with low erase counter to free physical eraseblocks with high - * erase counter. - */ -#define UBI_WL_THRESHOLD CONFIG_MTD_UBI_WL_THRESHOLD - -/* - * When a physical eraseblock is moved, the WL sub-system has to pick the target - * physical eraseblock to move to. The simplest way would be just to pick the - * one with the highest erase counter. But in certain workloads this could lead - * to an unlimited wear of one or few physical eraseblock. Indeed, imagine a - * situation when the picked physical eraseblock is constantly erased after the - * data is written to it. So, we have a constant which limits the highest erase - * counter of the free physical eraseblock to pick. Namely, the WL sub-system - * does not pick eraseblocks with erase counter greater than the lowest erase - * counter plus %WL_FREE_MAX_DIFF. - */ -#define WL_FREE_MAX_DIFF (2*UBI_WL_THRESHOLD) - /* * Maximum number of consecutive background thread failures which is enough to * switch to read-only mode. @@ -358,7 +337,7 @@ static struct ubi_wl_entry *find_wl_entry(struct ubi_device *ubi, * * This function looks for a wear leveling entry with medium erase counter, * but not greater or equivalent than the lowest erase counter plus - * %WL_FREE_MAX_DIFF/2. + * @ubi->wl_free_max_diff/2. */ static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi, struct rb_root *root) @@ -368,7 +347,7 @@ static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi, first = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); last = rb_entry(rb_last(root), struct ubi_wl_entry, u.rb); - if (last->ec - first->ec < WL_FREE_MAX_DIFF) { + if (last->ec - first->ec < ubi->wl_free_max_diff) { e = rb_entry(root->rb_node, struct ubi_wl_entry, u.rb); /* @@ -379,7 +358,7 @@ static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi, */ e = may_reserve_for_fm(ubi, e, root); } else - e = find_wl_entry(ubi, root, WL_FREE_MAX_DIFF/2, 0); + e = find_wl_entry(ubi, root, ubi->wl_free_max_diff/2, 0); return e; } @@ -706,7 +685,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, #ifdef CONFIG_MTD_UBI_FASTMAP e1 = find_anchor_wl_entry(&ubi->used); if (e1 && ubi->fm_anchor && - (ubi->fm_anchor->ec - e1->ec >= UBI_WL_THRESHOLD)) { + (ubi->fm_anchor->ec - e1->ec >= ubi->wl_threshold)) { ubi->fm_do_produce_anchor = 1; /* * fm_anchor is no longer considered a good anchor. @@ -743,7 +722,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, if (!e2) goto out_cancel; - if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) { + if (!(e2->ec - e1->ec >= ubi->wl_threshold)) { dbg_wl("no WL needed: min used EC %d, max free EC %d", e1->ec, e2->ec); @@ -1056,12 +1035,12 @@ static int ensure_wear_leveling(struct ubi_device *ubi, int nested) * We schedule wear-leveling only if the difference between the * lowest erase counter of used physical eraseblocks and a high * erase counter of free physical eraseblocks is greater than - * %UBI_WL_THRESHOLD. + * @ubi->wl_threshold. */ e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); - e2 = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF, 0); + e2 = find_wl_entry(ubi, &ubi->free, ubi->wl_free_max_diff, 0); - if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) + if (!(e2->ec - e1->ec >= ubi->wl_threshold)) goto out_unlock; #endif dbg_wl("schedule wear-leveling"); @@ -2090,7 +2069,7 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) { struct ubi_wl_entry *e; - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF, 0); + e = find_wl_entry(ubi, &ubi->free, ubi->wl_free_max_diff, 0); self_check_in_wl_tree(ubi, e, &ubi->free); ubi->free_count--; ubi_assert(ubi->free_count >= 0); diff --git a/include/uapi/mtd/ubi-user.h b/include/uapi/mtd/ubi-user.h index aa872a41ffb9..3538e11b5175 100644 --- a/include/uapi/mtd/ubi-user.h +++ b/include/uapi/mtd/ubi-user.h @@ -289,6 +289,13 @@ enum { * If @disable_fm is not zero, ubi doesn't create new fastmap even the module * param 'fm_autoconvert' is set, and existed old fastmap will be destroyed * after doing full scanning. + * + * The @wl_threshold defines the maximum difference between the highest and the + * lowest erase counter value of eraseblocks of this UBI device. When this + * threshold is exceeded, UBI starts performing wear leveling by means of + * moving data from eraseblock with low erase counter to eraseblocks with high + * erase counter. If @wl_threshold is zero, the default kernel value of + * %CONFIG_MTD_UBI_WL_THRESHOLD is used. The accepted range is 2-65536. */ struct ubi_attach_req { __s32 ubi_num; @@ -297,7 +304,8 @@ struct ubi_attach_req { __s16 max_beb_per1024; __s8 disable_fm; __s8 need_resv_pool; - __s8 padding[8]; + __s32 wl_threshold; + __s8 padding[4]; }; /* -- 2.52.0 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold 2026-07-23 2:02 ` Ran Hongyun @ 2026-07-23 3:01 ` Zhihao Cheng -1 siblings, 0 replies; 18+ messages in thread From: Zhihao Cheng @ 2026-07-23 3:01 UTC (permalink / raw) To: Ran Hongyun, richard, miquel.raynal, vigneshr, vapier, artem.bityutskiy Cc: linux-mtd, linux-kernel, yangerkun, yi.zhang 在 2026/7/23 10:02, Ran Hongyun 写道: > The UBI wear-leveling threshold (CONFIG_MTD_UBI_WL_THRESHOLD) is > currently a compile-time constant shared by all UBI devices. When a > single kernel image must support multiple NAND flashes with different > erase lifetimes, one global threshold cannot suit all devices. > > Add a per-device configurable wl_threshold parameter: > > - UAPI: add __s32 wl_threshold to struct ubi_attach_req, carved > from the existing padding. > > - Module parameter: ubi.mtd gains a new optional token > "wl_threshold": > ubi.mtd=0,0,0,0,0,0,256 ubi.mtd=1,0,0,0,0,0,4096 > > 0 means "use the kernel default", the accepted range is > 2-65536. > > Signed-off-by: Ran Hongyun <ranhongyun1@huawei.com> > --- > drivers/mtd/ubi/build.c | 43 ++++++++++++++++++++++++++++++------ > drivers/mtd/ubi/cdev.c | 2 +- > drivers/mtd/ubi/fastmap-wl.c | 8 +++---- > drivers/mtd/ubi/ubi.h | 21 +++++++++++++++++- > drivers/mtd/ubi/wl.c | 39 ++++++++------------------------ > include/uapi/mtd/ubi-user.h | 10 ++++++++- > 6 files changed, 79 insertions(+), 44 deletions(-) > Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com> ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold @ 2026-07-23 3:01 ` Zhihao Cheng 0 siblings, 0 replies; 18+ messages in thread From: Zhihao Cheng @ 2026-07-23 3:01 UTC (permalink / raw) To: Ran Hongyun, richard, miquel.raynal, vigneshr, vapier, artem.bityutskiy Cc: linux-mtd, linux-kernel, yangerkun, yi.zhang 在 2026/7/23 10:02, Ran Hongyun 写道: > The UBI wear-leveling threshold (CONFIG_MTD_UBI_WL_THRESHOLD) is > currently a compile-time constant shared by all UBI devices. When a > single kernel image must support multiple NAND flashes with different > erase lifetimes, one global threshold cannot suit all devices. > > Add a per-device configurable wl_threshold parameter: > > - UAPI: add __s32 wl_threshold to struct ubi_attach_req, carved > from the existing padding. > > - Module parameter: ubi.mtd gains a new optional token > "wl_threshold": > ubi.mtd=0,0,0,0,0,0,256 ubi.mtd=1,0,0,0,0,0,4096 > > 0 means "use the kernel default", the accepted range is > 2-65536. > > Signed-off-by: Ran Hongyun <ranhongyun1@huawei.com> > --- > drivers/mtd/ubi/build.c | 43 ++++++++++++++++++++++++++++++------ > drivers/mtd/ubi/cdev.c | 2 +- > drivers/mtd/ubi/fastmap-wl.c | 8 +++---- > drivers/mtd/ubi/ubi.h | 21 +++++++++++++++++- > drivers/mtd/ubi/wl.c | 39 ++++++++------------------------ > include/uapi/mtd/ubi-user.h | 10 ++++++++- > 6 files changed, 79 insertions(+), 44 deletions(-) > Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com> ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold 2026-07-23 2:02 ` Ran Hongyun @ 2026-07-23 6:06 ` Ran Hongyun -1 siblings, 0 replies; 18+ messages in thread From: Ran Hongyun @ 2026-07-23 6:06 UTC (permalink / raw) To: ranhongyun1 Cc: artem.bityutskiy, chengzhihao1, linux-kernel, linux-mtd, miquel.raynal, richard, vapier, vigneshr, yangerkun, yi.zhang Reply to the issues raised by sashiko: The struct size is unchanged, and all existing userspace programs zero-initialize the struct ubi_attach_req, so wl_threshold reads as zero and falls back to CONFIG_MTD_UBI_WL_THRESHOLD. No backward compatibility issue. ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold @ 2026-07-23 6:06 ` Ran Hongyun 0 siblings, 0 replies; 18+ messages in thread From: Ran Hongyun @ 2026-07-23 6:06 UTC (permalink / raw) To: ranhongyun1 Cc: artem.bityutskiy, chengzhihao1, linux-kernel, linux-mtd, miquel.raynal, richard, vapier, vigneshr, yangerkun, yi.zhang Reply to the issues raised by sashiko: The struct size is unchanged, and all existing userspace programs zero-initialize the struct ubi_attach_req, so wl_threshold reads as zero and falls back to CONFIG_MTD_UBI_WL_THRESHOLD. No backward compatibility issue. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold 2026-07-23 6:06 ` Ran Hongyun @ 2026-07-23 7:19 ` Richard Weinberger -1 siblings, 0 replies; 18+ messages in thread From: Richard Weinberger @ 2026-07-23 7:19 UTC (permalink / raw) To: Ran Hongyun Cc: Artem Bityutskiy, chengzhihao1, linux-kernel, linux-mtd, Miquel Raynal, vapier, Vignesh Raghavendra, yangerkun, yi zhang ----- Ursprüngliche Mail ----- > Von: "Ran Hongyun" <ranhongyun1@huawei.com> > An: ranhongyun1@huawei.com > CC: "Artem Bityutskiy" <artem.bityutskiy@linux.intel.com>, "chengzhihao1" <chengzhihao1@huawei.com>, "linux-kernel" > <linux-kernel@vger.kernel.org>, "linux-mtd" <linux-mtd@lists.infradead.org>, "Miquel Raynal" > <miquel.raynal@bootlin.com>, "richard" <richard@nod.at>, vapier@gentoo.org, "Vignesh Raghavendra" <vigneshr@ti.com>, > "yangerkun" <yangerkun@huawei.com>, "yi zhang" <yi.zhang@huawei.com> > Gesendet: Donnerstag, 23. Juli 2026 08:06:43 > Betreff: Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold > Reply to the issues raised by sashiko: The struct size is unchanged, > and all existing userspace programs zero-initialize the struct > ubi_attach_req, so wl_threshold reads as zero and falls back to > CONFIG_MTD_UBI_WL_THRESHOLD. No backward compatibility issue. I don't see Sashiko's mail. Where was it sent to? Thanks, //richard ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold @ 2026-07-23 7:19 ` Richard Weinberger 0 siblings, 0 replies; 18+ messages in thread From: Richard Weinberger @ 2026-07-23 7:19 UTC (permalink / raw) To: Ran Hongyun Cc: Artem Bityutskiy, chengzhihao1, linux-kernel, linux-mtd, Miquel Raynal, vapier, Vignesh Raghavendra, yangerkun, yi zhang ----- Ursprüngliche Mail ----- > Von: "Ran Hongyun" <ranhongyun1@huawei.com> > An: ranhongyun1@huawei.com > CC: "Artem Bityutskiy" <artem.bityutskiy@linux.intel.com>, "chengzhihao1" <chengzhihao1@huawei.com>, "linux-kernel" > <linux-kernel@vger.kernel.org>, "linux-mtd" <linux-mtd@lists.infradead.org>, "Miquel Raynal" > <miquel.raynal@bootlin.com>, "richard" <richard@nod.at>, vapier@gentoo.org, "Vignesh Raghavendra" <vigneshr@ti.com>, > "yangerkun" <yangerkun@huawei.com>, "yi zhang" <yi.zhang@huawei.com> > Gesendet: Donnerstag, 23. Juli 2026 08:06:43 > Betreff: Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold > Reply to the issues raised by sashiko: The struct size is unchanged, > and all existing userspace programs zero-initialize the struct > ubi_attach_req, so wl_threshold reads as zero and falls back to > CONFIG_MTD_UBI_WL_THRESHOLD. No backward compatibility issue. I don't see Sashiko's mail. Where was it sent to? Thanks, //richard ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold 2026-07-23 2:02 ` Ran Hongyun @ 2026-07-23 8:16 ` Ran Hongyun -1 siblings, 0 replies; 18+ messages in thread From: Ran Hongyun @ 2026-07-23 8:16 UTC (permalink / raw) To: ranhongyun1 Cc: artem.bityutskiy, chengzhihao1, linux-kernel, linux-mtd, miquel.raynal, richard, vapier, vigneshr, yangerkun, yi.zhang Here is the link to Sashiko's comments https://sashiko.dev/#/message/20260723020233.3079997-3-ranhongyun1%40huawei.com Thanks, Ran Hongyun ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold @ 2026-07-23 8:16 ` Ran Hongyun 0 siblings, 0 replies; 18+ messages in thread From: Ran Hongyun @ 2026-07-23 8:16 UTC (permalink / raw) To: ranhongyun1 Cc: artem.bityutskiy, chengzhihao1, linux-kernel, linux-mtd, miquel.raynal, richard, vapier, vigneshr, yangerkun, yi.zhang Here is the link to Sashiko's comments https://sashiko.dev/#/message/20260723020233.3079997-3-ranhongyun1%40huawei.com Thanks, Ran Hongyun ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold 2026-07-23 8:16 ` Ran Hongyun @ 2026-07-23 8:30 ` Richard Weinberger -1 siblings, 0 replies; 18+ messages in thread From: Richard Weinberger @ 2026-07-23 8:30 UTC (permalink / raw) To: Ran Hongyun Cc: Artem Bityutskiy, chengzhihao1, linux-kernel, linux-mtd, Miquel Raynal, vapier, Vignesh Raghavendra, yangerkun, yi zhang ----- Ursprüngliche Mail ----- > Von: "Ran Hongyun" <ranhongyun1@huawei.com> > An: "Ran Hongyun" <ranhongyun1@huawei.com> > CC: "Artem Bityutskiy" <artem.bityutskiy@linux.intel.com>, "chengzhihao1" <chengzhihao1@huawei.com>, "linux-kernel" > <linux-kernel@vger.kernel.org>, "linux-mtd" <linux-mtd@lists.infradead.org>, "Miquel Raynal" > <miquel.raynal@bootlin.com>, "richard" <richard@nod.at>, "vapier" <vapier@gentoo.org>, "Vignesh Raghavendra" > <vigneshr@ti.com>, "yangerkun" <yangerkun@huawei.com>, "yi zhang" <yi.zhang@huawei.com> > Gesendet: Donnerstag, 23. Juli 2026 10:16:39 > Betreff: Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold > Here is the link to Sashiko's comments > https://sashiko.dev/#/message/20260723020233.3079997-3-ranhongyun1%40huawei.com I saw that but I expected it to send a mail :-) Thanks, //richard ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold @ 2026-07-23 8:30 ` Richard Weinberger 0 siblings, 0 replies; 18+ messages in thread From: Richard Weinberger @ 2026-07-23 8:30 UTC (permalink / raw) To: Ran Hongyun Cc: Artem Bityutskiy, chengzhihao1, linux-kernel, linux-mtd, Miquel Raynal, vapier, Vignesh Raghavendra, yangerkun, yi zhang ----- Ursprüngliche Mail ----- > Von: "Ran Hongyun" <ranhongyun1@huawei.com> > An: "Ran Hongyun" <ranhongyun1@huawei.com> > CC: "Artem Bityutskiy" <artem.bityutskiy@linux.intel.com>, "chengzhihao1" <chengzhihao1@huawei.com>, "linux-kernel" > <linux-kernel@vger.kernel.org>, "linux-mtd" <linux-mtd@lists.infradead.org>, "Miquel Raynal" > <miquel.raynal@bootlin.com>, "richard" <richard@nod.at>, "vapier" <vapier@gentoo.org>, "Vignesh Raghavendra" > <vigneshr@ti.com>, "yangerkun" <yangerkun@huawei.com>, "yi zhang" <yi.zhang@huawei.com> > Gesendet: Donnerstag, 23. Juli 2026 10:16:39 > Betreff: Re: [PATCH 2/2] UBI: support per-device wear-leveling threshold > Here is the link to Sashiko's comments > https://sashiko.dev/#/message/20260723020233.3079997-3-ranhongyun1%40huawei.com I saw that but I expected it to send a mail :-) Thanks, //richard ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2026-07-23 8:30 UTC | newest] Thread overview: 18+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-23 2:02 [PATCH 0/2] UBI: fix ubi.mtd MODULE_PARM_DESC issues and add per-device wear-leveling threshold Ran Hongyun 2026-07-23 2:02 ` Ran Hongyun 2026-07-23 2:02 ` [PATCH 1/2] UBI: fix two issues in the ubi.mtd MODULE_PARM_DESC Ran Hongyun 2026-07-23 2:02 ` Ran Hongyun 2026-07-23 2:40 ` Zhihao Cheng 2026-07-23 2:40 ` Zhihao Cheng 2026-07-23 2:02 ` [PATCH 2/2] UBI: support per-device wear-leveling threshold Ran Hongyun 2026-07-23 2:02 ` Ran Hongyun 2026-07-23 3:01 ` Zhihao Cheng 2026-07-23 3:01 ` Zhihao Cheng 2026-07-23 6:06 ` Ran Hongyun 2026-07-23 6:06 ` Ran Hongyun 2026-07-23 7:19 ` Richard Weinberger 2026-07-23 7:19 ` Richard Weinberger 2026-07-23 8:16 ` Ran Hongyun 2026-07-23 8:16 ` Ran Hongyun 2026-07-23 8:30 ` Richard Weinberger 2026-07-23 8:30 ` Richard Weinberger
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.