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

Rickard Andersson rickard.andersson at axis.com
Fri Oct 4 01:22:06 PDT 2024


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.

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))
+			peb_count = UBI_FM_MAX_START;
+		else
+			return 0; /* No fastmap on this UBI device */
+	}
+
+	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,
-- 
2.30.2




More information about the linux-mtd mailing list