From: Shmulik Ladkani <shmulik.ladkani@gmail.com>
To: Artem Bityutskiy <dedekind1@gmail.com>
Cc: Shmulik Ladkani <shmulik.ladkani@gmail.com>,
linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org,
Richard Weinberger <richard@nod.at>,
Richard Genoud <richard.genoud@gmail.com>
Subject: [PATCH 2/5] ubi: Limit amount of reserved eraseblocks for bad PEB handling
Date: Wed, 4 Jul 2012 11:06:01 +0300 [thread overview]
Message-ID: <1341389164-24409-3-git-send-email-shmulik.ladkani@gmail.com> (raw)
In-Reply-To: <1341389164-24409-1-git-send-email-shmulik.ladkani@gmail.com>
The existing mechanism of reserving PEBs for bad PEB handling has two
flaws:
- It is calculated as a percentage of good PEBs instead of total PEBs.
- There's no limit on the amount of PEBs UBI reserves for future bad
eraseblock handling.
This patch changes the mechanism to overcome these flaws.
The desired level of PEBs reserved for bad PEB handling (beb_rsvd_level)
is set to the maximum expected bad eraseblocks (bad_peb_limit) minus the
existing number of bad eraseblocks (bad_peb_count).
The actual amount of PEBs reserved for bad PEB handling is usually set
to the desired level (but in some circumstances may be lower than the
desired level, e.g. when attaching to a device that has too few
available PEBs to satisfy the desired level).
In the case where the device has too many bad PEBs (above the expected
limit), then the desired level, and the actual amount of PEBs reserved
are set to zero. No PEBs will be set aside for future bad eraseblock
handling - even if some PEBs are made available (e.g. by shrinking a
volume).
If another PEB goes bad, and there are available PEBs, then the
eraseblock will be marked bad (consuming one available PEB). But if
there are no available PEBs, ubi will go into readonly mode.
Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
---
drivers/mtd/ubi/Kconfig | 8 ++++++++
drivers/mtd/ubi/misc.c | 16 ++++++++++++----
drivers/mtd/ubi/wl.c | 44 ++++++++++++++++++++++++++++----------------
3 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig
index 8df256f..7eb91cb 100644
--- a/drivers/mtd/ubi/Kconfig
+++ b/drivers/mtd/ubi/Kconfig
@@ -47,8 +47,16 @@ config MTD_UBI_BEB_LIMIT
default 2
range 0 25
help
+ If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI
+ reserves some amount of physical eraseblocks to handle new bad
+ eraseblocks.
This option specifies the maximum bad eraseblocks UBI expects on the
ubi device (percents of total number of flash eraseblocks).
+ This limit is used in order to derive amount of eraseblock UBI
+ reserves for handling new bad blocks.
+ If the device has more bad eraseblocks than this limit, UBI does not
+ reserve any physical eraseblocks for new bad eraseblocks, but
+ attempts to use available eraseblocks (if any).
If the underlying flash does not admit of bad eraseblocks (e.g. NOR
flash), this value is ignored.
Leave the default value if unsure.
diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c
index f6a7d7a..e9dcb83 100644
--- a/drivers/mtd/ubi/misc.c
+++ b/drivers/mtd/ubi/misc.c
@@ -98,10 +98,18 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id)
*/
void ubi_calculate_reserved(struct ubi_device *ubi)
{
- ubi->beb_rsvd_level = ubi->good_peb_count/100;
- ubi->beb_rsvd_level *= CONFIG_MTD_UBI_BEB_RESERVE;
- if (ubi->beb_rsvd_level < MIN_RESEVED_PEBS)
- ubi->beb_rsvd_level = MIN_RESEVED_PEBS;
+ /*
+ * Calculate the actual number of PEBs currently needed to be reserved
+ * for future bad eraseblock handling.
+ */
+ ubi->beb_rsvd_level = ubi->bad_peb_limit - ubi->bad_peb_count;
+ if (ubi->beb_rsvd_level < 0) {
+ ubi->beb_rsvd_level = 0;
+ ubi_warn("number of bad PEBs (%d) is above the expected limit "
+ "(%d), not reserving any PEBs for bad PEB handling, "
+ "will use available PEBs (if any)",
+ ubi->bad_peb_count, ubi->bad_peb_limit);
+ }
}
/**
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index b6be644..9143f35 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -978,9 +978,10 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
int cancel)
{
struct ubi_wl_entry *e = wl_wrk->e;
- int pnum = e->pnum, err, need;
+ int pnum = e->pnum, err;
int vol_id = wl_wrk->vol_id;
int lnum = wl_wrk->lnum;
+ int available_consumed = 0;
if (cancel) {
dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec);
@@ -1045,20 +1046,14 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
}
spin_lock(&ubi->volumes_lock);
- need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs + 1;
- if (need > 0) {
- need = ubi->avail_pebs >= need ? need : ubi->avail_pebs;
- ubi->avail_pebs -= need;
- ubi->rsvd_pebs += need;
- ubi->beb_rsvd_pebs += need;
- if (need > 0)
- ubi_msg("reserve more %d PEBs", need);
- }
-
if (ubi->beb_rsvd_pebs == 0) {
- spin_unlock(&ubi->volumes_lock);
- ubi_err("no reserved physical eraseblocks");
- goto out_ro;
+ if (ubi->avail_pebs == 0) {
+ spin_unlock(&ubi->volumes_lock);
+ ubi_err("no reserved/available physical eraseblocks");
+ goto out_ro;
+ }
+ ubi->avail_pebs -= 1;
+ available_consumed = 1;
}
spin_unlock(&ubi->volumes_lock);
@@ -1068,11 +1063,23 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
goto out_ro;
spin_lock(&ubi->volumes_lock);
- ubi->beb_rsvd_pebs -= 1;
+ if (ubi->beb_rsvd_pebs > 0) {
+ if (available_consumed) {
+ /*
+ * Some PEBs were added to the reserved pool since we
+ * last checked. Use a PEB from the reserved pool.
+ */
+ ubi->avail_pebs += 1;
+ available_consumed = 0;
+ }
+ ubi->beb_rsvd_pebs -= 1;
+ }
ubi->bad_peb_count += 1;
ubi->good_peb_count -= 1;
ubi_calculate_reserved(ubi);
- if (ubi->beb_rsvd_pebs)
+ if (available_consumed)
+ ubi_warn("no PEBs in the reserved pool, used an available PEB");
+ else if (ubi->beb_rsvd_pebs)
ubi_msg("%d PEBs left in the reserve", ubi->beb_rsvd_pebs);
else
ubi_warn("last PEB from the reserved pool was used");
@@ -1081,6 +1088,11 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
return err;
out_ro:
+ if (available_consumed) {
+ spin_lock(&ubi->volumes_lock);
+ ubi->avail_pebs += 1;
+ spin_unlock(&ubi->volumes_lock);
+ }
ubi_ro_mode(ubi);
return err;
}
--
1.7.9
next prev parent reply other threads:[~2012-07-04 8:08 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-04 8:05 [PATCH 0/5] ubi: Fix bad PEBs reserve caclulation Shmulik Ladkani
2012-07-04 8:06 ` [PATCH 1/5] ubi: introduce ubi->bad_peb_limit Shmulik Ladkani
2012-07-18 7:09 ` Artem Bityutskiy
2012-07-18 10:40 ` Artem Bityutskiy
2012-07-19 6:16 ` Shmulik Ladkani
2012-07-30 13:00 ` Artem Bityutskiy
2012-07-04 8:06 ` Shmulik Ladkani [this message]
2012-07-09 10:15 ` [PATCH 2/5] ubi: Limit amount of reserved eraseblocks for bad PEB handling Richard Genoud
2012-07-09 11:02 ` Shmulik Ladkani
2012-07-18 10:28 ` Artem Bityutskiy
2012-07-18 11:01 ` Artem Bityutskiy
2012-07-18 19:55 ` Shmulik Ladkani
2012-07-19 3:35 ` Artem Bityutskiy
2012-07-18 11:40 ` Artem Bityutskiy
2012-07-04 8:06 ` [PATCH 3/5] ubi: kill CONFIG_MTD_UBI_BEB_RESERVE Shmulik Ladkani
2012-07-04 8:06 ` [PATCH 4/5] ubi: trivial: fix comment of ubi_calculate_reserved() Shmulik Ladkani
2012-07-18 10:38 ` Artem Bityutskiy
2012-07-04 8:06 ` [PATCH 5/5] ubi: harmonize the update of ubi->beb_rsvd_pebs Shmulik Ladkani
2012-07-18 11:32 ` Artem Bityutskiy
2012-07-04 8:35 ` [PATCH 0/5] ubi: Fix bad PEBs reserve caclulation Richard Weinberger
2012-07-04 11:33 ` Shmulik Ladkani
2012-07-06 15:27 ` Richard Genoud
2012-07-07 6:14 ` Shmulik Ladkani
2012-07-07 8:32 ` Richard Genoud
2012-07-09 6:58 ` Richard Genoud
2012-07-16 15:33 ` Artem Bityutskiy
2012-07-17 7:23 ` Shmulik Ladkani
2012-07-18 6:54 ` Artem Bityutskiy
2012-07-30 13:56 ` Artem Bityutskiy
2012-07-31 8:19 ` Shmulik Ladkani
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=1341389164-24409-3-git-send-email-shmulik.ladkani@gmail.com \
--to=shmulik.ladkani@gmail.com \
--cc=dedekind1@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=richard.genoud@gmail.com \
--cc=richard@nod.at \
/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;
as well as URLs for NNTP newsgroup(s).