From: Alexander Schmidt <alexs@linux.vnet.ibm.com>
To: Artem.Bityutskiy@nokia.com,
"linux-mtd@lists.infradead.org" <linux-mtd@lists.infradead.org>
Subject: [RFC] [PATCH] UBI: refine wear leveling logic
Date: Wed, 28 Mar 2007 15:47:18 +0200 [thread overview]
Message-ID: <200703281547.18851.alexs@linux.vnet.ibm.com> (raw)
Hi,
This patch addresses the handling of blocks that are put by the user
while they are moved by the wear leveling thread. The schedule_erase
function is now called by put_peb() itself instead of notifying the wear
leveling thread.
Comments are welcome...
Signed-off-by: Alexander Schmidt <alexs@linux.vnet.ibm.com>
---
drivers/mtd/ubi/ubi.h | 2 -
drivers/mtd/ubi/wl.c | 77 ++++++++------------------------------------------
2 files changed, 13 insertions(+), 66 deletions(-)
--- dedekind-ubi-2.6.orig/drivers/mtd/ubi/ubi.h
+++ dedekind-ubi-2.6/drivers/mtd/ubi/ubi.h
@@ -316,8 +316,6 @@ struct ubi_device {
unsigned long long abs_ec;
struct ubi_wl_entry *move_from;
struct ubi_wl_entry *move_to;
- int move_from_put;
- int move_to_put;
struct list_head works;
int works_count;
struct task_struct *bgt_thread;
--- dedekind-ubi-2.6.orig/drivers/mtd/ubi/wl.c
+++ dedekind-ubi-2.6/drivers/mtd/ubi/wl.c
@@ -793,7 +793,7 @@ static int schedule_erase(struct ubi_dev
static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
int cancel)
{
- int err, put = 0;
+ int err;
struct ubi_wl_entry *e1, *e2;
struct ubi_vid_hdr *vid_hdr;
@@ -864,7 +864,6 @@ static int wear_leveling_worker(struct u
free_tree_del(ubi, e2);
ubi_assert(!ubi->move_from && !ubi->move_to);
- ubi_assert(!ubi->move_to_put && !ubi->move_from_put);
ubi->move_from = e1;
ubi->move_to = e2;
spin_unlock(&ubi->wl_lock);
@@ -907,28 +906,11 @@ static int wear_leveling_worker(struct u
ubi_free_vid_hdr(ubi, vid_hdr);
spin_lock(&ubi->wl_lock);
- if (unlikely(!ubi->move_to_put))
- used_tree_add(ubi, e2);
- else
- put = 1;
+ used_tree_add(ubi, e2);
ubi->move_from = ubi->move_to = NULL;
- ubi->move_from_put = ubi->move_to_put = 0;
ubi->wl_scheduled = 0;
spin_unlock(&ubi->wl_lock);
- if (unlikely(put)) {
- /*
- * Well, the target PEB was put meanwhile, schedule it for
- * erasure.
- */
- dbg_wl("PEB %d was put meanwhile, erase", e2->pnum);
- err = schedule_erase(ubi, e2, 0);
- if (unlikely(err)) {
- kmem_cache_free(wl_entries_slab, e2);
- ubi_ro_mode(ubi);
- }
- }
-
err = schedule_erase(ubi, e1, 0);
if (unlikely(err)) {
kmem_cache_free(wl_entries_slab, e1);
@@ -950,27 +932,10 @@ error:
ubi_free_vid_hdr(ubi, vid_hdr);
spin_lock(&ubi->wl_lock);
ubi->wl_scheduled = 0;
- if (ubi->move_from_put)
- put = 1;
- else
- used_tree_add(ubi, e1);
+ used_tree_add(ubi, e1);
ubi->move_from = ubi->move_to = NULL;
- ubi->move_from_put = ubi->move_to_put = 0;
spin_unlock(&ubi->wl_lock);
- if (put) {
- /*
- * Well, the target PEB was put meanwhile, schedule it for
- * erasure.
- */
- dbg_wl("PEB %d was put meanwhile, erase", e1->pnum);
- err = schedule_erase(ubi, e1, 0);
- if (unlikely(err)) {
- kmem_cache_free(wl_entries_slab, e1);
- ubi_ro_mode(ubi);
- }
- }
-
err = schedule_erase(ubi, e2, 0);
if (unlikely(err)) {
kmem_cache_free(wl_entries_slab, e2);
@@ -1183,34 +1148,18 @@ int ubi_wl_put_peb(struct ubi_device *ub
if (unlikely(e == ubi->move_from)) {
/*
* User is putting the physical eraseblock which was selected to
- * be moved. It will be scheduled for erasure in the
- * wear-leveling worker.
- */
- dbg_wl("PEB %d is being moved", pnum);
- ubi_assert(!ubi->move_from_put);
- ubi->move_from_put = 1;
- spin_unlock(&ubi->wl_lock);
- return 0;
- } else if (unlikely(e == ubi->move_to)) {
- /*
- * User is putting the physical eraseblock which was selected
- * as the target the data is moved to. It may happen if the EBA
- * unit already re-mapped the LEB but the WL unit did has not
- * put the PEB to the "used" tree.
+ * be moved. Schedule the destination block for erasure.
*/
- dbg_wl("PEB %d is the target of data moving", pnum);
- ubi_assert(!ubi->move_to_put);
- ubi->move_to_put = 1;
- spin_unlock(&ubi->wl_lock);
- return 0;
- } else {
- if (in_wl_tree(e, &ubi->used))
- used_tree_del(ubi, e);
- else if (unlikely(in_wl_tree(e, &ubi->scrub)))
- scrub_tree_del(ubi, e);
- else
- prot_tree_del(ubi, e->pnum);
+ dbg_wl("PEB %d is being moved");
+ e = ubi->move_to;
}
+
+ if (in_wl_tree(e, &ubi->used))
+ used_tree_del(ubi, e);
+ else if (unlikely(in_wl_tree(e, &ubi->scrub)))
+ scrub_tree_del(ubi, e);
+ else if (!in_wl_tree(e, &ubi->free))
+ prot_tree_del(ubi, e->pnum);
spin_unlock(&ubi->wl_lock);
err = schedule_erase(ubi, e, torture);
next reply other threads:[~2007-03-28 13:47 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-28 13:47 Alexander Schmidt [this message]
2007-03-29 10:36 ` [RFC] [PATCH] UBI: refine wear leveling logic Artem Bityutskiy
2007-03-29 11:59 ` Alexander Schmidt
2007-03-30 12:23 ` Artem Bityutskiy
2007-03-30 14:40 ` Alexander Schmidt
2007-04-02 10:53 ` Artem Bityutskiy
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=200703281547.18851.alexs@linux.vnet.ibm.com \
--to=alexs@linux.vnet.ibm.com \
--cc=Artem.Bityutskiy@nokia.com \
--cc=linux-mtd@lists.infradead.org \
/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