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 ioctl for detailed erase counters
Date: Mon, 25 Nov 2024 14:48:20 +0100 [thread overview]
Message-ID: <20241125134820.560648-2-rickard.andersson@axis.com> (raw)
In-Reply-To: <20241125134820.560648-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
detailed 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.
Signed-off-by: Rickard Andersson <rickard.andersson@axis.com>
---
drivers/mtd/ubi/cdev.c | 86 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 0d8f04cf03c5..4af99ddbba66 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -828,6 +828,86 @@ static int rename_volumes(struct ubi_device *ubi,
return err;
}
+
+static int ubi_get_ec_info(struct ubi_device *ubi, void __user *argp)
+{
+ struct ubi_ecinfo_req *req;
+ struct ubi_wl_entry *wl;
+ int peb;
+ int end_peb;
+ int i;
+ int err = 0;
+
+ req = kzalloc(sizeof(struct ubi_ecinfo_req), GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ /* Copy just the input arguments */
+ err = copy_from_user(req, argp, sizeof(struct ubi_ecinfo_req) -
+ offsetof(struct ubi_ecinfo_req, end_ec_res));
+ if (err) {
+ err = -EFAULT;
+ goto out_free;
+ }
+
+ /* Make sure that start value is less or equal to end value */
+ if (req->start_ec_req > req->end_ec_req) {
+ err = -EINVAL;
+ goto out_free;
+ }
+
+ /* Check input argument start value */
+ if ((req->start_ec_req < 0 || req->start_ec_req >= ubi->peb_count)) {
+ err = -EINVAL;
+ goto out_free;
+ }
+
+ /* Check if end value is less than 0 */
+ if (req->end_ec_req < 0) {
+ err = -EINVAL;
+ goto out_free;
+ }
+
+ end_peb = req->end_ec_req;
+
+ /* Control end value */
+ if (end_peb > ubi->peb_count)
+ end_peb = ubi->peb_count;
+
+ /* Check that we do not overwrite our working memory */
+ if (end_peb > (ARRAY_SIZE(req->erase_counters) + req->start_ec_req))
+ end_peb = ARRAY_SIZE(req->erase_counters) + req->start_ec_req;
+
+ i = 0;
+ for (peb = req->start_ec_req; peb < end_peb; i++, peb++) {
+
+ if (ubi_io_is_bad(ubi, peb)) {
+ req->erase_counters[i] = UBI_UNKNOWN;
+ continue;
+ }
+
+ spin_lock(&ubi->wl_lock);
+
+ wl = ubi->lookuptbl[peb];
+ if (wl)
+ req->erase_counters[i] = wl->ec;
+ else
+ req->erase_counters[i] = UBI_UNKNOWN;
+
+ spin_unlock(&ubi->wl_lock);
+ }
+
+ /* Return last read peb */
+ req->end_ec_res = end_peb - 1;
+
+ if (copy_to_user(argp, req, sizeof(struct ubi_ecinfo_req)))
+ err = -EFAULT;
+
+out_free:
+ kfree(req);
+ return err;
+}
+
static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
@@ -991,6 +1071,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/
next prev parent reply other threads:[~2024-11-25 13:48 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-25 13:48 [PATCH 1/2] ubi: Expose interface for detailed erase counters Rickard Andersson
2024-11-25 13:48 ` Rickard Andersson [this message]
2024-11-25 15:44 ` Richard Weinberger
2024-11-25 15:45 ` Richard Weinberger
2024-11-26 5:09 ` 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=20241125134820.560648-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.