From: Bean Huo <jackyard88@gmail.com>
To: richard@nod.at, dedekind1@gmail.com, adrian.hunter@intel.com,
computersforpeace@gmail.com, boris.brezillon@free-electrons.com
Cc: beanhuo@micron.com, linux-mtd@lists.infradead.org,
linux-kernel@vger.kernel.org, zszubbocsev@micron.com,
peterpandong@micron.com
Subject: [PATCH v2 09/17] drivers:mtd:ubi:get PEB according to specfied plane number
Date: Tue, 2 Feb 2016 02:30:44 +0000 [thread overview]
Message-ID: <1454380252-16170-10-git-send-email-jackyard88@gmail.com> (raw)
In-Reply-To: <1454380252-16170-1-git-send-email-jackyard88@gmail.com>
From: Bean Huo <beanhuo@micron.com>
This patch is to add new functions in order to get one free PEB according
to specified plane number. Currently, bakvol only support parallel
nand with dual plane.
Signed-off-by: BeanHuo <beanhuo@micron.com>
---
drivers/mtd/ubi/wl.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 140 insertions(+)
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 275d9fb..de8e348 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -140,6 +140,7 @@ static int self_check_in_wl_tree(const struct ubi_device *ubi,
struct ubi_wl_entry *e, struct rb_root *root);
static int self_check_in_pq(const struct ubi_device *ubi,
struct ubi_wl_entry *e);
+static int produce_free_peb(struct ubi_device *ubi);
/**
* wl_tree_add - add a wear-leveling entry to a WL RB-tree.
@@ -341,6 +342,47 @@ static struct ubi_wl_entry *find_wl_entry(struct ubi_device *ubi,
return e;
}
+static struct ubi_wl_entry *find_wl_plane_entry(struct ubi_device *ubi,
+ struct rb_root *root, int diff, int plane)
+{
+ struct rb_node *p;
+ struct ubi_wl_entry *e, *prev_e = NULL, *bk_e = NULL;
+ int max;
+
+ e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb);
+ max = e->ec + diff;
+
+ p = root->rb_node;
+ while (p) {
+ struct ubi_wl_entry *e1;
+
+ e1 = rb_entry(p, struct ubi_wl_entry, u.rb);
+ if (e1->ec >= max)
+ p = p->rb_left;
+ else {
+ p = p->rb_right;
+ if (e->pnum%2 == plane)
+ prev_e = e;
+
+ e = e1;
+
+ if (e1->pnum%2 == plane)
+ bk_e = e1;
+ }
+ }
+
+ /**
+ *If no fastmap has been written and this WL entry can be used
+ * as anchor PEB, hold it back and return the second best WL entry
+ * such that fastmap can use the anchor PEB later.
+ **/
+ if (prev_e && !ubi->fm_disabled &&
+ !ubi->fm && bk_e->pnum < UBI_FM_MAX_START)
+ return prev_e;
+
+ return bk_e;
+}
+
/**
* find_mean_wl_entry - find wear-leveling entry with medium erase counter.
* @ubi: UBI device description object
@@ -371,6 +413,32 @@ static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi,
return e;
}
+static struct ubi_wl_entry *find_mean_plane_wl_entry(struct ubi_device *ubi,
+ struct rb_root *root, int plane)
+{
+ struct ubi_wl_entry *e, *first, *last;
+ struct rb_node *rb;
+
+ rb = root->rb_node;
+ 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) {
+ /* Currently, bakvol doesn't support fastmap */
+ while (rb) {
+ e = rb_entry(rb, struct ubi_wl_entry, u.rb);
+ if (e->pnum%2 == plane)
+ break;
+ rb = rb_next(rb);
+ /* Only returns specified plane peb */
+ e = NULL;
+ }
+ } else
+ e = find_wl_plane_entry(ubi, root, WL_FREE_MAX_DIFF/2, plane);
+
+ return e;
+}
+
/**
* wl_get_wle - get a mean wl entry to be used by ubi_wl_get_peb() or
* refill_wl_user_pool().
@@ -403,6 +471,38 @@ static struct ubi_wl_entry *wl_get_wle(struct ubi_device *ubi)
}
/**
+ * wl_get_wle_plane - get a mean wl entry to be used by ubi_wl_get_plane_peb() or
+ * refill_wl_user_pool().
+ * @ubi: UBI device description object
+ * @plane: plane number
+ *
+ * This function returns a a wear leveling entry in case of success and
+ * NULL in case of failure.
+ */
+static struct ubi_wl_entry *wl_get_plane_wle(struct ubi_device *ubi, int plane)
+{
+ struct ubi_wl_entry *e;
+
+ e = find_mean_plane_wl_entry(ubi, &ubi->free, plane);
+ if (!e) {
+ ubi_err(ubi, "get mean plane eraseblocks failed");
+ return NULL;
+ }
+
+ self_check_in_wl_tree(ubi, e, &ubi->free);
+
+ /*
+ * Move the physical eraseblock to the protection queue where it will
+ * be protected from being moved for some time.
+ */
+ rb_erase(&e->u.rb, &ubi->free);
+ ubi->free_count--;
+ dbg_wl("PEB %d EC %d", e->pnum, e->ec);
+
+ return e;
+}
+
+/**
* prot_queue_del - remove a physical eraseblock from the protection queue.
* @ubi: UBI device description object
* @pnum: the physical eraseblock to remove
@@ -1751,6 +1851,7 @@ static int self_check_in_pq(const struct ubi_device *ubi,
dump_stack();
return -EINVAL;
}
+
#ifndef CONFIG_MTD_UBI_FASTMAP
static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
{
@@ -1839,6 +1940,45 @@ retry:
return e->pnum;
}
+
+int ubi_wl_get_plane_peb(struct ubi_device *ubi, int plane)
+{
+ int err;
+ struct ubi_wl_entry *e;
+
+retry:
+ spin_lock(&ubi->wl_lock);
+ if (!ubi->free.rb_node) {
+ if (ubi->works_count == 0) {
+ ubi_err(ubi, "no free eraseblocks");
+ ubi_assert(list_empty(&ubi->works));
+ spin_unlock(&ubi->wl_lock);
+ return -ENOSPC;
+ }
+
+ err = produce_free_peb(ubi);
+ if (err < 0) {
+ spin_unlock(&ubi->wl_lock);
+ return err;
+ }
+ spin_unlock(&ubi->wl_lock);
+ goto retry;
+
+ }
+ e = wl_get_plane_wle(ubi, plane);
+ prot_queue_add(ubi, e);
+ spin_unlock(&ubi->wl_lock);
+
+ err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset,
+ ubi->peb_size - ubi->vid_hdr_aloffset);
+ if (err) {
+ ubi_err(ubi, "new PEB %d does not contain all 0xFF bytes", e->pnum);
+ return err;
+ }
+
+ return e->pnum;
+}
+
#else
#include "fastmap-wl.c"
#endif
--
1.9.1
next prev parent reply other threads:[~2016-02-02 2:33 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-02 2:30 [PATCH v2 00/17] Add a bakvol module in UBI layer for MLC paired page power loss issue Bean Huo
2016-02-02 2:30 ` [PATCH v2 01/17] include:mtd:add multi-plane page program command Bean Huo
2016-02-02 2:30 ` [PATCH v2 02/17] include:mtd:add multi-plane program in mtd_info Bean Huo
2016-02-02 2:30 ` [PATCH v2 03/17] drivers:mtd:add dual plane page program support in partition layer Bean Huo
2016-02-02 3:00 ` kbuild test robot
2016-02-02 2:30 ` [PATCH v2 04/17] drivers:mtd:nand:enable dual plane page program function Bean Huo
2016-02-02 3:04 ` kbuild test robot
2016-02-02 2:30 ` [PATCH v2 05/17] drivers:mtd:ubi:add bakvol on-flash and RAM data structures Bean Huo
2016-02-02 2:30 ` [PATCH v2 06/17] drivers:mtd:ubi:add bakvol function define in ubi layer Bean Huo
2016-02-02 3:05 ` kbuild test robot
2016-02-02 3:08 ` kbuild test robot
2016-02-02 2:30 ` [PATCH v2 07/17] fs:ubifs:add bakvol function define in ubifs layer Bean Huo
2016-02-02 2:30 ` [PATCH v2 08/17] drivers:mtd:ubi:disable bakvol function while writing volume table Bean Huo
2016-02-02 2:30 ` Bean Huo [this message]
2016-02-02 2:30 ` [PATCH v2 10/17] drivers:mtd:ubi:enable bakvol function for fastmap operation Bean Huo
2016-02-02 2:30 ` [PATCH v2 11/17] drivers:mtd:ubi:add disable/enable bakvol while ubi write Bean Huo
2016-02-02 2:30 ` [PATCH v2 12/17] drivers:mtd:ubi:add disable bakvol while ubi detach Bean Huo
2016-02-02 2:30 ` [PATCH v2 13/17] drivers:mtd:ubi:add bakvol init while attach ubi Bean Huo
2016-02-02 2:30 ` [PATCH v2 14/17] drivers:mtd:ubi:add backup operation in ubi_io_write Bean Huo
2016-02-02 3:22 ` kbuild test robot
2016-02-02 2:30 ` [PATCH v2 15/17] fs:ubifs:enable bakvol module and recover operation Bean Huo
2016-02-02 2:30 ` Bean Huo
2016-02-02 2:30 ` [PATCH v2 16/17] driver:mtd:ubi:add new bakvol module in ubi layer Bean Huo
2016-02-02 2:30 ` [PATCH v2 17/17] drivers:mtd:ubi: Kconfig Makefile Bean Huo
2016-02-02 3:22 ` kbuild test robot
2016-02-02 3:56 ` kbuild test robot
2016-02-02 3:58 ` kbuild test robot
2016-02-02 4:15 ` Bean Huo 霍斌斌 (beanhuo)
2016-02-03 0:46 ` Brian Norris
2016-02-03 6:14 ` Bean Huo 霍斌斌 (beanhuo)
2016-02-02 23:06 ` [PATCH v2 00/17] Add a bakvol module in UBI layer for MLC paired page power loss issue Richard Weinberger
2016-02-03 6:11 ` Bean Huo 霍斌斌 (beanhuo)
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=1454380252-16170-10-git-send-email-jackyard88@gmail.com \
--to=jackyard88@gmail.com \
--cc=adrian.hunter@intel.com \
--cc=beanhuo@micron.com \
--cc=boris.brezillon@free-electrons.com \
--cc=computersforpeace@gmail.com \
--cc=dedekind1@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=peterpandong@micron.com \
--cc=richard@nod.at \
--cc=zszubbocsev@micron.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.