diff mbox series

[v2,03/10] ubi: Expose max erase counter for fastmap in sysfs

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

Commit Message

Rickard Andersson Oct. 11, 2024, 9:21 a.m. UTC
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(+)

Comments

Zhihao Cheng Oct. 11, 2024, 12:03 p.m. UTC | #1
在 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 mbox series

Patch

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,