public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
From: Rickard Andersson <rickard.andersson@axis.com>
To: <richard@nod.at>, <chengzhihao1@huawei.com>,
	<linux-mtd@lists.infradead.org>, <rickard314.andersson@gmail.com>
Cc: <rickard.andersson@axis.com>, <kernel@axis.com>
Subject: [PATCH 2/2] ubi: Implement 'UBI_IOCECNFO' for reading erase counters
Date: Thu, 21 Nov 2024 11:21:57 +0100	[thread overview]
Message-ID: <20241121102157.3498056-2-rickard.andersson@axis.com> (raw)
In-Reply-To: <20241121102157.3498056-1-rickard.andersson@axis.com>

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/

  reply	other threads:[~2024-11-21 10:22 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-21 10:21 [PATCH 1/2] ubi: Expose interface for reading erase counters Rickard Andersson
2024-11-21 10:21 ` Rickard Andersson [this message]
2024-11-21 10:37 ` Richard Weinberger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241121102157.3498056-2-rickard.andersson@axis.com \
    --to=rickard.andersson@axis.com \
    --cc=chengzhihao1@huawei.com \
    --cc=kernel@axis.com \
    --cc=linux-mtd@lists.infradead.org \
    --cc=richard@nod.at \
    --cc=rickard314.andersson@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox