* [PATCH 2/2] ubi: Implement 'UBI_IOCECNFO' for reading erase counters
2024-11-21 10:21 [PATCH 1/2] ubi: Expose interface for reading erase counters Rickard Andersson
@ 2024-11-21 10:21 ` Rickard Andersson
2024-11-21 10:37 ` [PATCH 1/2] ubi: Expose interface " Richard Weinberger
1 sibling, 0 replies; 3+ messages in thread
From: Rickard Andersson @ 2024-11-21 10:21 UTC (permalink / raw)
To: richard, chengzhihao1, linux-mtd, rickard314.andersson
Cc: rickard.andersson, kernel
Currently, only "max_ec" can be read from sysfs, which provides a
limited view of the flash device’s wear. In certain cases, such as
bugs in the wear-leveling algorithm, specific blocks can be worn down
more than others, resulting in uneven wear distribution. Providing
mean erase counter values give a better understanding of the overall
flash wear.
There exists more detailed info in debugfs, but this information is
only available for debug builds.
This patch calculates the mean and max values only when they are
requested. This calculation typically takes 2.7 ms for an UBI device
with 4091 blocks running on a single core Cortex-A9 at 792 MHz.
Signed-off-by: Rickard Andersson <rickard.andersson@axis.com>
---
drivers/mtd/ubi/cdev.c | 75 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 0d8f04cf03c5..2b3545826609 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -828,6 +828,75 @@ static int rename_volumes(struct ubi_device *ubi,
return err;
}
+static int ubi_get_info(struct ubi_device *ubi, void __user *argp)
+{
+ struct ubi_ecinfo_res info;
+ struct ubi_wl_entry *wl;
+ int peb;
+ int ec_count = 0;
+ int ec_count_fastmap = 0;
+ uint64_t ec_sum = 0;
+ uint64_t ec_sum_fastmap = 0;
+ int max_ec = 0;
+ int max_ec_data = 0;
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ const bool fastmap = true;
+#else
+ const bool fastmap = false;
+#endif
+ memset(&info, 0, sizeof(info));
+
+ for (peb = 0; peb < ubi->peb_count; peb++) {
+ int err;
+
+ /*
+ * We have looped through the fastmap blocks, lets store fastmap data if
+ * fastmap is enabled.
+ */
+ if (fastmap && peb == UBI_FM_MAX_START) {
+ ec_sum_fastmap = ec_sum;
+ ec_count_fastmap = ec_count;
+ info.mean_ec_fastmap = div_u64(ec_sum_fastmap, ec_count_fastmap);
+ info.max_ec_fastmap = max_ec;
+ }
+
+ err = ubi_io_is_bad(ubi, peb);
+ if (err)
+ continue;
+
+ spin_lock(&ubi->wl_lock);
+
+ wl = ubi->lookuptbl[peb];
+ if (wl) {
+ ec_sum += wl->ec;
+ ec_count++;
+
+ if (max_ec < wl->ec)
+ max_ec = wl->ec;
+ if (fastmap && (peb >= UBI_FM_MAX_START) && (max_ec_data < wl->ec))
+ max_ec_data = wl->ec;
+ }
+
+ spin_unlock(&ubi->wl_lock);
+ }
+
+ if (ec_count > 0) {
+ info.max_ec = max_ec;
+ info.mean_ec = div_u64(ec_sum, ec_count);
+
+ if (fastmap && (ec_count > ec_count_fastmap)) {
+ info.mean_ec_data = div_u64(ec_sum - ec_sum_fastmap,
+ ec_count - ec_count_fastmap);
+ info.max_ec_data = max_ec_data;
+ }
+ }
+
+ if (copy_to_user(argp, &info, sizeof(info)))
+ return -EFAULT;
+
+ return 0;
+}
+
static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
@@ -991,6 +1060,12 @@ static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
break;
}
+ case UBI_IOCECNFO:
+ {
+ err = ubi_get_info(ubi, argp);
+ break;
+ }
+
default:
err = -ENOTTY;
break;
--
2.30.2
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH 1/2] ubi: Expose interface for reading erase counters
2024-11-21 10:21 [PATCH 1/2] ubi: Expose interface for reading erase counters Rickard Andersson
2024-11-21 10:21 ` [PATCH 2/2] ubi: Implement 'UBI_IOCECNFO' " Rickard Andersson
@ 2024-11-21 10:37 ` Richard Weinberger
1 sibling, 0 replies; 3+ messages in thread
From: Richard Weinberger @ 2024-11-21 10:37 UTC (permalink / raw)
To: Rickard X Andersson; +Cc: chengzhihao1, linux-mtd, rickard314 andersson, kernel
Rickard,
----- Ursprüngliche Mail -----
> Von: "Rickard X Andersson" <rickard.andersson@axis.com>
> An: "richard" <richard@nod.at>, "chengzhihao1" <chengzhihao1@huawei.com>, "linux-mtd" <linux-mtd@lists.infradead.org>,
> "rickard314 andersson" <rickard314.andersson@gmail.com>
> CC: "Rickard X Andersson" <rickard.andersson@axis.com>, "kernel" <kernel@axis.com>
> Gesendet: Donnerstag, 21. November 2024 11:21:56
> Betreff: [PATCH 1/2] ubi: Expose interface for reading erase counters
> Using the ioctl command 'UBI_IOCECNFO' user space can obtain mean
> and max erase counters of a device. If fastmap is enabled also erase
> counter information of that area and its complementary area is
> provided.
the idea was having an ioctl interface to get the EC counters of all PEBs.
Such that userspace can do the mean/max/min calculations on it's own.
That way the kernel interface is clean and generic. Userspace can interpret
the data as it needs.
Thanks,
//richard
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 3+ messages in thread