From patchwork Fri Jun 1 15:16:33 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [12/23] ubi: fastmap: harmonize medium erase-counter seek algorithm Date: Fri, 01 Jun 2012 05:16:33 -0000 From: Richard Weinberger X-Patchwork-Id: 162334 Message-Id: <1338563804-85990-13-git-send-email-richard@nod.at> To: linux-mtd@lists.infradead.org Cc: dedekind1@gmail.com, Richard Weinberger , adrian.hunter@intel.com, Heinz.Egger@linutronix.de, shmulik.ladkani@gmail.com, tglx@linutronix.de, tim.bird@am.sony.com From: Shmulik Ladkani Currently, there are two different locations where a wear-leveling entry with a medium erase counter is looked-for, with the same search algorithm duplicated. Harmonize this by introducing a common function 'find_mean_wl_entry'. Signed-off-by: Shmulik Ladkani Signed-off-by: Richard Weinberger --- drivers/mtd/ubi/wl.c | 50 +++++++++++++++++++++++++++++--------------------- 1 files changed, 29 insertions(+), 21 deletions(-) diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 0e4d935..2325d3d 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -386,6 +386,29 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff) } /** + * find_mean_wl_entry - find wear-leveling entry with medium erase counter. + * @root: the RB-tree where to look for + * + * This function looks for a wear leveling entry with medium erase counter, + * but not greater or equivalent than the lowest erase counter plus + * %WL_FREE_MAX_DIFF/2. + */ +static struct ubi_wl_entry *find_mean_wl_entry(struct rb_root *root) +{ + struct ubi_wl_entry *e, *first, *last; + + first = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); + last = rb_entry(rb_last(root), struct ubi_wl_entry, u.rb); + + if (last->ec - first->ec < WL_FREE_MAX_DIFF) + e = rb_entry(root->rb_node, struct ubi_wl_entry, u.rb); + else + e = find_wl_entry(root, WL_FREE_MAX_DIFF/2); + + return e; +} + +/** * find_early_wl_entry - find wear-leveling entry with the lowest pnum. * @root: the RB-tree where to look for * @max_pnum: highest possible pnum @@ -419,7 +442,7 @@ static struct ubi_wl_entry *find_early_wl_entry(struct rb_root *root, int ubi_wl_get_fm_peb(struct ubi_device *ubi, int max_pnum) { int ret = -ENOSPC; - struct ubi_wl_entry *e, *first, *last; + struct ubi_wl_entry *e; if (!ubi->free.rb_node) { ubi_err("no free eraseblocks"); @@ -427,18 +450,9 @@ int ubi_wl_get_fm_peb(struct ubi_device *ubi, int max_pnum) goto out; } - if (max_pnum < 0) { - first = rb_entry(rb_first(&ubi->free), - struct ubi_wl_entry, u.rb); - last = rb_entry(rb_last(&ubi->free), - struct ubi_wl_entry, u.rb); - - if (last->ec - first->ec < WL_FREE_MAX_DIFF) - e = rb_entry(ubi->free.rb_node, - struct ubi_wl_entry, u.rb); - else - e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2); - } else + if (max_pnum < 0) + e = find_mean_wl_entry(&ubi->free); + else e = find_early_wl_entry(&ubi->free, max_pnum); if (!e) @@ -464,7 +478,7 @@ out: static int __ubi_wl_get_peb(struct ubi_device *ubi) { int err; - struct ubi_wl_entry *e, *first, *last; + struct ubi_wl_entry *e; retry: spin_lock(&ubi->wl_lock); @@ -483,13 +497,7 @@ retry: goto retry; } - first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb); - last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, u.rb); - - if (last->ec - first->ec < WL_FREE_MAX_DIFF) - e = rb_entry(ubi->free.rb_node, struct ubi_wl_entry, u.rb); - else - e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2); + e = find_mean_wl_entry(&ubi->free); self_check_in_wl_tree(ubi, e, &ubi->free);