linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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

  parent reply	other threads:[~2016-02-02  2:37 UTC|newest]

Thread overview: 31+ 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 ` [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 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).