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 v2 2/2] ubi: Implement ioctl for detailed erase counters
Date: Wed, 27 Nov 2024 10:10:50 +0100	[thread overview]
Message-ID: <20241127091050.1254359-2-rickard.andersson@axis.com> (raw)
In-Reply-To: <20241127091050.1254359-1-rickard.andersson@axis.com>

Currently, "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. Also some use cases
can wear the erase blocks of the fastmap area more heavily than other
parts of flash.
Providing detailed erase counter values give a better understanding of
the overall flash wear and is needed to be able to calculate for example
expected life time.
There exists more detailed info in debugfs, but this information is
only available for debug builds.

Signed-off-by: Rickard Andersson <rickard.andersson@axis.com>
---
 drivers/mtd/ubi/cdev.c | 96 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 0d8f04cf03c5..681cf8526e2f 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -828,6 +828,96 @@ static int rename_volumes(struct ubi_device *ubi,
 	return err;
 }
 
+
+static int ubi_get_ec_info(struct ubi_device *ubi, struct ubi_ecinfo_req __user *ureq)
+{
+	struct ubi_ecinfo_req req;
+	struct ubi_wl_entry *wl;
+	int i;
+	int peb;
+	int end_peb;
+	int err = 0;
+	int max_elem;
+	int32_t *erase_counters;
+
+	/* Copy the input arguments */
+	err = copy_from_user(&req, ureq, sizeof(struct ubi_ecinfo_req));
+	if (err) {
+		err = -EFAULT;
+		goto out;
+	}
+
+	/* Check input arguments */
+	if (req.length <= 0 || req.start < 0) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	max_elem = req.length;
+
+	/* We can not read more than the total amount of PEBs */
+	if (max_elem > ubi->peb_count)
+		max_elem = ubi->peb_count;
+
+	/* Check for overflow */
+	if (req.start + max_elem < req.start) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	erase_counters = kmalloc_array(max_elem,
+				       sizeof(int32_t),
+				       GFP_KERNEL);
+	if (!erase_counters) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	end_peb = req.start + max_elem;
+	if (end_peb > ubi->peb_count)
+		end_peb = ubi->peb_count;
+
+	i = 0;
+	for (peb = req.start; peb < end_peb; i++, peb++) {
+		int ec;
+
+		if (ubi_io_is_bad(ubi, peb)) {
+			erase_counters[i] = UBI_UNKNOWN;
+			continue;
+		}
+
+		spin_lock(&ubi->wl_lock);
+
+		wl = ubi->lookuptbl[peb];
+		if (wl)
+			ec = wl->ec;
+		else
+			ec = UBI_UNKNOWN;
+
+		spin_unlock(&ubi->wl_lock);
+
+		erase_counters[i] = ec;
+	}
+
+	/* Return actual read length */
+	req.read_length = i;
+
+	/* Copy everything except erase counter array */
+	if (copy_to_user(ureq, &req, sizeof(struct ubi_ecinfo_req))) {
+		err = -EFAULT;
+		goto out_free;
+	}
+
+	/* Copy erase counter array */
+	if (copy_to_user(ureq->erase_counters, erase_counters, max_elem * sizeof(int32_t)))
+		err = -EFAULT;
+
+ out_free:
+	kfree(erase_counters);
+ out:
+	return err;
+}
+
 static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
 			   unsigned long arg)
 {
@@ -991,6 +1081,12 @@ static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
 		break;
 	}
 
+	case UBI_IOCECNFO:
+	{
+		err = ubi_get_ec_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-27  9:11 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-27  9:10 [PATCH v2 1/2] ubi: Expose interface for detailed erase counters Rickard Andersson
2024-11-27  9:10 ` Rickard Andersson [this message]
2024-12-03 19:09   ` [PATCH v2 2/2] ubi: Implement ioctl " Richard Weinberger
2024-12-04  1:59     ` Zhihao Cheng

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=20241127091050.1254359-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