public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH 1/2] ubi: Expose interface for reading erase counters
@ 2024-11-21 10:21 Rickard Andersson
  2024-11-21 10:21 ` [PATCH 2/2] ubi: Implement 'UBI_IOCECNFO' " Rickard Andersson
  2024-11-21 10:37 ` [PATCH 1/2] ubi: Expose interface " Richard Weinberger
  0 siblings, 2 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

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.

Signed-off-by: Rickard Andersson <rickard.andersson@axis.com>
---
 include/uapi/mtd/ubi-user.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/include/uapi/mtd/ubi-user.h b/include/uapi/mtd/ubi-user.h
index e1571603175e..00cc8a083675 100644
--- a/include/uapi/mtd/ubi-user.h
+++ b/include/uapi/mtd/ubi-user.h
@@ -175,6 +175,8 @@
 #define UBI_IOCRPEB _IOW(UBI_IOC_MAGIC, 4, __s32)
 /* Force scrubbing on the specified PEB */
 #define UBI_IOCSPEB _IOW(UBI_IOC_MAGIC, 5, __s32)
+/* Read detailed device information */
+#define UBI_IOCECNFO _IOR(UBI_IOC_MAGIC, 6, struct ubi_ecinfo_res)
 
 /* ioctl commands of the UBI control character device */
 
@@ -470,4 +472,27 @@ struct ubi_blkcreate_req {
 	__s8  padding[128];
 }  __packed;
 
+/**
+ * struct ubi_ecinfo_res - a data structure used in UBI device erase count
+ * information responses.
+ *
+ * @max_ec: Max physical erase block erase counter value of whole UBI device
+ * @mean_ec: Mean physical erase block erase counter value of whole UBI device
+ * @max_ec_fastmap: Max physical erase block erase counter value of fastmap area
+ * @mean_ec_fastmap: Mean physical erase block erase counter value of fastmap area
+ * @max_ec_data: Max physical erase block erase counter value of data area
+ * @mean_ec_data: Mean physical erase block erase counter value of data area
+ *
+ * @padding: reserved for future, not used, has to be zeroed
+ */
+struct ubi_ecinfo_res {
+	__s32 max_ec;
+	__s32 mean_ec;
+	__s32 max_ec_fastmap;
+	__s32 mean_ec_fastmap;
+	__s32 max_ec_data;
+	__s32 mean_ec_data;
+	__s8  padding[64];
+}  __packed;
+
 #endif /* __UBI_USER_H__ */
-- 
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

* [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

end of thread, other threads:[~2024-11-21 10:37 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH 1/2] ubi: Expose interface " Richard Weinberger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox