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 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.