Message ID | 20241011092134.2909496-3-rickard.andersson@axis.com |
---|---|
State | New |
Headers | show |
Series | [v2,01/10] ubi: Expose mean erase counter in sysfs | expand |
在 2024/10/11 17:21, Rickard Andersson 写道: > Since the fastmap area has its own wear levelling it is valuable to > provide a max erase counter value specifically for that area. > > Signed-off-by: Rickard Andersson <rickard.andersson@axis.com> > --- > drivers/mtd/ubi/build.c | 44 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 44 insertions(+) > > diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c > index 3633c743e7d1..f5a3a3f7d490 100644 > --- a/drivers/mtd/ubi/build.c > +++ b/drivers/mtd/ubi/build.c > @@ -134,6 +134,8 @@ static struct device_attribute dev_max_ec = > static struct device_attribute dev_mean_ec = > __ATTR(mean_ec, S_IRUGO, dev_attribute_show, NULL); > #ifdef CONFIG_MTD_UBI_FASTMAP > +static struct device_attribute dev_max_ec_fastmap = > + __ATTR(max_ec_fastmap, S_IRUGO, dev_attribute_show, NULL); > static struct device_attribute dev_mean_ec_fastmap = > __ATTR(mean_ec_fastmap, S_IRUGO, dev_attribute_show, NULL); > #endif > @@ -386,6 +388,45 @@ static int ubi_calc_mean_ec(struct ubi_device *ubi, int start_peb, int end_peb) > return mean_ec; > } > > +/** > + * ubi_calc_max_ec_fastmap - calculate max erase counter value. > + * @ubi: UBI device description object > + * @start_peb: First PEB in the range > + * @end_peb: End PEB in the half-open range > + * > + * Returns the max erase counter value that can be found in the range. > + * Range is half-open i.e end_peb is not actually included. > + * Returns zero if it was not possible to calculate the max ec value Delete this line from the comments, since zero is a normal value if all PEBs' erase counter is initialized as '0' by ubiformat tool. > + */ > +#ifdef CONFIG_MTD_UBI_FASTMAP > +static int ubi_calc_max_ec(struct ubi_device *ubi, int start_peb, int end_peb) > +{ > + struct ubi_wl_entry *wl; > + int peb; > + int max_ec = 0; > + > + for (peb = start_peb; peb < end_peb; peb++) { > + int err; > + > + err = ubi_io_is_bad(ubi, peb); > + if (err) > + continue; > + > + spin_lock(&ubi->wl_lock); > + > + wl = ubi->lookuptbl[peb]; > + if (wl) { > + if (max_ec < wl->ec) > + max_ec = wl->ec; > + } > + > + spin_unlock(&ubi->wl_lock); > + } > + > + return max_ec; > +} > +#endif > + > /* "Show" method for files in '/<sysfs>/class/ubi/ubiX/' */ > static ssize_t dev_attribute_show(struct device *dev, > struct device_attribute *attr, char *buf) > @@ -418,6 +459,8 @@ static ssize_t dev_attribute_show(struct device *dev, > else if (attr == &dev_mean_ec) > ret = sprintf(buf, "%d\n", ubi_calc_mean_ec(ubi, 0, ubi->peb_count)); > #ifdef CONFIG_MTD_UBI_FASTMAP > + else if (attr == &dev_max_ec_fastmap) > + ret = sprintf(buf, "%d\n", ubi_calc_max_ec(ubi, 0, UBI_FM_MAX_START)); > else if (attr == &dev_mean_ec_fastmap) > ret = sprintf(buf, "%d\n", ubi_calc_mean_ec(ubi, 0, UBI_FM_MAX_START)); > #endif > @@ -449,6 +492,7 @@ static struct attribute *ubi_dev_attrs[] = { > &dev_max_ec.attr, > &dev_mean_ec.attr, > #ifdef CONFIG_MTD_UBI_FASTMAP > + &dev_max_ec_fastmap.attr, > &dev_mean_ec_fastmap.attr, > #endif > &dev_reserved_for_bad.attr, >
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 3633c743e7d1..f5a3a3f7d490 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -134,6 +134,8 @@ static struct device_attribute dev_max_ec = static struct device_attribute dev_mean_ec = __ATTR(mean_ec, S_IRUGO, dev_attribute_show, NULL); #ifdef CONFIG_MTD_UBI_FASTMAP +static struct device_attribute dev_max_ec_fastmap = + __ATTR(max_ec_fastmap, S_IRUGO, dev_attribute_show, NULL); static struct device_attribute dev_mean_ec_fastmap = __ATTR(mean_ec_fastmap, S_IRUGO, dev_attribute_show, NULL); #endif @@ -386,6 +388,45 @@ static int ubi_calc_mean_ec(struct ubi_device *ubi, int start_peb, int end_peb) return mean_ec; } +/** + * ubi_calc_max_ec_fastmap - calculate max erase counter value. + * @ubi: UBI device description object + * @start_peb: First PEB in the range + * @end_peb: End PEB in the half-open range + * + * Returns the max erase counter value that can be found in the range. + * Range is half-open i.e end_peb is not actually included. + * Returns zero if it was not possible to calculate the max ec value + */ +#ifdef CONFIG_MTD_UBI_FASTMAP +static int ubi_calc_max_ec(struct ubi_device *ubi, int start_peb, int end_peb) +{ + struct ubi_wl_entry *wl; + int peb; + int max_ec = 0; + + for (peb = start_peb; peb < end_peb; peb++) { + int err; + + err = ubi_io_is_bad(ubi, peb); + if (err) + continue; + + spin_lock(&ubi->wl_lock); + + wl = ubi->lookuptbl[peb]; + if (wl) { + if (max_ec < wl->ec) + max_ec = wl->ec; + } + + spin_unlock(&ubi->wl_lock); + } + + return max_ec; +} +#endif + /* "Show" method for files in '/<sysfs>/class/ubi/ubiX/' */ static ssize_t dev_attribute_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -418,6 +459,8 @@ static ssize_t dev_attribute_show(struct device *dev, else if (attr == &dev_mean_ec) ret = sprintf(buf, "%d\n", ubi_calc_mean_ec(ubi, 0, ubi->peb_count)); #ifdef CONFIG_MTD_UBI_FASTMAP + else if (attr == &dev_max_ec_fastmap) + ret = sprintf(buf, "%d\n", ubi_calc_max_ec(ubi, 0, UBI_FM_MAX_START)); else if (attr == &dev_mean_ec_fastmap) ret = sprintf(buf, "%d\n", ubi_calc_mean_ec(ubi, 0, UBI_FM_MAX_START)); #endif @@ -449,6 +492,7 @@ static struct attribute *ubi_dev_attrs[] = { &dev_max_ec.attr, &dev_mean_ec.attr, #ifdef CONFIG_MTD_UBI_FASTMAP + &dev_max_ec_fastmap.attr, &dev_mean_ec_fastmap.attr, #endif &dev_reserved_for_bad.attr,
Since the fastmap area has its own wear levelling it is valuable to provide a max erase counter value specifically for that area. Signed-off-by: Rickard Andersson <rickard.andersson@axis.com> --- drivers/mtd/ubi/build.c | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)