Commit 7b6c32da authored by Xiaochuan-Xu's avatar Xiaochuan-Xu Committed by Artem Bityutskiy

UBI: simplify PEB protection code

UBI has 2 RB-trees to implement PEB protection, which is too
much for simply prevent PEB from being moved for some time.
This patch implements this using lists. The benefits:

1. No need to allocate protection entry on each PEB get.
2. No need to maintain balanced trees and walk them.
Signed-off-by: default avatarXiaochuan-Xu <xiaochuan-xu@cqu.edu.cn>
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
parent 23553b2c
...@@ -73,6 +73,13 @@ ...@@ -73,6 +73,13 @@
*/ */
#define UBI_IO_RETRIES 3 #define UBI_IO_RETRIES 3
/*
* Length of the protection queue. The length is effectively equivalent to the
* number of (global) erase cycles PEBs are protected from the wear-leveling
* worker.
*/
#define UBI_PROT_QUEUE_LEN 10
/* /*
* Error codes returned by the I/O sub-system. * Error codes returned by the I/O sub-system.
* *
...@@ -96,6 +103,7 @@ enum { ...@@ -96,6 +103,7 @@ enum {
/** /**
* struct ubi_wl_entry - wear-leveling entry. * struct ubi_wl_entry - wear-leveling entry.
* @u.rb: link in the corresponding (free/used) RB-tree * @u.rb: link in the corresponding (free/used) RB-tree
* @u.list: link in the protection queue
* @ec: erase counter * @ec: erase counter
* @pnum: physical eraseblock number * @pnum: physical eraseblock number
* *
...@@ -106,6 +114,7 @@ enum { ...@@ -106,6 +114,7 @@ enum {
struct ubi_wl_entry { struct ubi_wl_entry {
union { union {
struct rb_node rb; struct rb_node rb;
struct list_head list;
} u; } u;
int ec; int ec;
int pnum; int pnum;
...@@ -290,7 +299,7 @@ struct ubi_wl_entry; ...@@ -290,7 +299,7 @@ struct ubi_wl_entry;
* @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling * @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling
* *
* @autoresize_vol_id: ID of the volume which has to be auto-resized at the end * @autoresize_vol_id: ID of the volume which has to be auto-resized at the end
* of UBI ititializetion * of UBI initialization
* @vtbl_slots: how many slots are available in the volume table * @vtbl_slots: how many slots are available in the volume table
* @vtbl_size: size of the volume table in bytes * @vtbl_size: size of the volume table in bytes
* @vtbl: in-RAM volume table copy * @vtbl: in-RAM volume table copy
...@@ -308,18 +317,17 @@ struct ubi_wl_entry; ...@@ -308,18 +317,17 @@ struct ubi_wl_entry;
* @used: RB-tree of used physical eraseblocks * @used: RB-tree of used physical eraseblocks
* @free: RB-tree of free physical eraseblocks * @free: RB-tree of free physical eraseblocks
* @scrub: RB-tree of physical eraseblocks which need scrubbing * @scrub: RB-tree of physical eraseblocks which need scrubbing
* @prot: protection trees * @pq: protection queue (contain physical eraseblocks which are temporarily
* @prot.pnum: protection tree indexed by physical eraseblock numbers * protected from the wear-leveling worker)
* @prot.aec: protection tree indexed by absolute erase counter value * @pq_head: protection queue head
* @wl_lock: protects the @used, @free, @prot, @lookuptbl, @abs_ec, @move_from, * @wl_lock: protects the @used, @free, @pq, @pq_head, @lookuptbl, @move_from,
* @move_to, @move_to_put @erase_pending, @wl_scheduled, and @works * @move_to, @move_to_put @erase_pending, @wl_scheduled and @works
* fields * fields
* @move_mutex: serializes eraseblock moves * @move_mutex: serializes eraseblock moves
* @work_sem: sycnhronizes the WL worker with use tasks * @work_sem: synchronizes the WL worker with use tasks
* @wl_scheduled: non-zero if the wear-leveling was scheduled * @wl_scheduled: non-zero if the wear-leveling was scheduled
* @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any * @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any
* physical eraseblock * physical eraseblock
* @abs_ec: absolute erase counter
* @move_from: physical eraseblock from where the data is being moved * @move_from: physical eraseblock from where the data is being moved
* @move_to: physical eraseblock where the data is being moved to * @move_to: physical eraseblock where the data is being moved to
* @move_to_put: if the "to" PEB was put * @move_to_put: if the "to" PEB was put
...@@ -353,11 +361,11 @@ struct ubi_wl_entry; ...@@ -353,11 +361,11 @@ struct ubi_wl_entry;
* *
* @peb_buf1: a buffer of PEB size used for different purposes * @peb_buf1: a buffer of PEB size used for different purposes
* @peb_buf2: another buffer of PEB size used for different purposes * @peb_buf2: another buffer of PEB size used for different purposes
* @buf_mutex: proptects @peb_buf1 and @peb_buf2 * @buf_mutex: protects @peb_buf1 and @peb_buf2
* @ckvol_mutex: serializes static volume checking when opening * @ckvol_mutex: serializes static volume checking when opening
* @mult_mutex: serializes operations on multiple volumes, like re-nameing * @mult_mutex: serializes operations on multiple volumes, like re-naming
* @dbg_peb_buf: buffer of PEB size used for debugging * @dbg_peb_buf: buffer of PEB size used for debugging
* @dbg_buf_mutex: proptects @dbg_peb_buf * @dbg_buf_mutex: protects @dbg_peb_buf
*/ */
struct ubi_device { struct ubi_device {
struct cdev cdev; struct cdev cdev;
...@@ -394,16 +402,13 @@ struct ubi_device { ...@@ -394,16 +402,13 @@ struct ubi_device {
struct rb_root used; struct rb_root used;
struct rb_root free; struct rb_root free;
struct rb_root scrub; struct rb_root scrub;
struct { struct list_head pq[UBI_PROT_QUEUE_LEN];
struct rb_root pnum; int pq_head;
struct rb_root aec;
} prot;
spinlock_t wl_lock; spinlock_t wl_lock;
struct mutex move_mutex; struct mutex move_mutex;
struct rw_semaphore work_sem; struct rw_semaphore work_sem;
int wl_scheduled; int wl_scheduled;
struct ubi_wl_entry **lookuptbl; struct ubi_wl_entry **lookuptbl;
unsigned long long abs_ec;
struct ubi_wl_entry *move_from; struct ubi_wl_entry *move_from;
struct ubi_wl_entry *move_to; struct ubi_wl_entry *move_to;
int move_to_put; int move_to_put;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment