[PATCH 2/4] ubi: Expose mean erase counter for fastmap in sysfs

Zhihao Cheng chengzhihao1 at huawei.com
Tue Oct 8 02:27:29 PDT 2024


在 2024/10/4 16:22, Rickard Andersson 写道:
> Since the fastmap area has its own wear levelling it is valuable to
> provide a mean value for that area. This value can be used in order
> to estimate life expectancy of the flash.
> 

There are 2 cases shown as following:
1) fastmap is disabled: We can determine whether the wear-leveling 
algorithm works fine by comparing 'max_ec' with 'mean_ec'.
2) fastmap is enabled: The max_ec may come from first 64 PEBs(fastmap 
area), or it may come from data area(pnum > 64), how can we determine 
whether the wear-leveling algorithm works fine for data area?
> Signed-off-by: Rickard Andersson <rickard.andersson at axis.com>
> ---
>   drivers/mtd/ubi/build.c | 29 ++++++++++++++++++++++++-----
>   1 file changed, 24 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
> index 8bdfc51cacb1..af67cefd3e5e 100644
> --- a/drivers/mtd/ubi/build.c
> +++ b/drivers/mtd/ubi/build.c
> @@ -133,6 +133,8 @@ static struct device_attribute dev_max_ec =
>   	__ATTR(max_ec, S_IRUGO, dev_attribute_show, NULL);
>   static struct device_attribute dev_mean_ec =
>   	__ATTR(mean_ec, S_IRUGO, dev_attribute_show, NULL);
> +static struct device_attribute dev_mean_ec_fastmap =
> +	__ATTR(mean_ec_fastmap, S_IRUGO, dev_attribute_show, NULL);
>   static struct device_attribute dev_reserved_for_bad =
>   	__ATTR(reserved_for_bad, S_IRUGO, dev_attribute_show, NULL);
>   static struct device_attribute dev_bad_peb_count =
> @@ -345,19 +347,33 @@ int ubi_major2num(int major)
>   /**
>    * ubi_calc_mean_ec - calculate mean erase counter value.
>    * @ubi: UBI device description object
> + * @fastmap: true if mean value of just the fastmap area should be calculated
>    *
> - * Returns the mean value of the all blocks of the device.
> - * Returns zero if it was not possible to calculate the mean value.
> + * Returns the mean value of the all non-bad blocks of the device if fastmap is
> + * false.
> + * If fastmap is true then only a mean value of the fastmap area is calculated.
> + * Returns zero if it was not possible to calculate the mean value or if no
> + * fastmap exists.
>    */
> -int ubi_calc_mean_ec(struct ubi_device *ubi)
> +int ubi_calc_mean_ec(struct ubi_device *ubi, bool fastmap)
>   {
>   	struct ubi_wl_entry *wl;
>   	int peb;
>   	int ec_count = 0;
> +	int peb_count;
>   	int mean_ec = 0;
>   	uint64_t ec_sum = 0;
>   
> -	for (peb = 0; peb < ubi->peb_count; peb++) {
> +	peb_count = ubi->peb_count;
> +
> +	if (fastmap) {
> +		if ((!ubi->fm_disabled) && (peb_count > UBI_FM_MAX_START))

'if (!ubi->fm_disabled))' is enough.
> +			peb_count = UBI_FM_MAX_START;
> +		else
> +			return 0; /* No fastmap on this UBI device */

If we format /dev/mtdX by command 'ubiformat -e 0', the return value '0' 
may confuse us, it means that the fastmap is disabled or the 
mean_ec_fastmap is 0.
> +	}
> +
> +	for (peb = 0; peb < peb_count; peb++) {
>   		int err;
>   
>   		err = ubi_io_is_bad(ubi, peb);
> @@ -411,7 +427,9 @@ static ssize_t dev_attribute_show(struct device *dev,
>   	else if (attr == &dev_max_ec)
>   		ret = sprintf(buf, "%d\n", ubi->max_ec);
>   	else if (attr == &dev_mean_ec)
> -		ret = sprintf(buf, "%d\n", ubi_calc_mean_ec(ubi));
> +		ret = sprintf(buf, "%d\n", ubi_calc_mean_ec(ubi, false));
> +	else if (attr == &dev_mean_ec_fastmap)
> +		ret = sprintf(buf, "%d\n", ubi_calc_mean_ec(ubi, true));
>   	else if (attr == &dev_reserved_for_bad)
>   		ret = sprintf(buf, "%d\n", ubi->beb_rsvd_pebs);
>   	else if (attr == &dev_bad_peb_count)
> @@ -439,6 +457,7 @@ static struct attribute *ubi_dev_attrs[] = {
>   	&dev_volumes_count.attr,
>   	&dev_max_ec.attr,
>   	&dev_mean_ec.attr,
> +	&dev_mean_ec_fastmap.attr,
>   	&dev_reserved_for_bad.attr,
>   	&dev_bad_peb_count.attr,
>   	&dev_max_vol_count.attr,
> 




More information about the linux-mtd mailing list