diff options
author | Richard Weinberger <richard@nod.at> | 2014-11-10 15:39:17 +0100 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2015-03-26 22:17:47 +0100 |
commit | 6830356466a57db21c7bc31bf3be4e61189e145b (patch) | |
tree | 881282f4d06ed98f9aed6bbfaa4b3dbc32b588c8 /drivers/mtd | |
parent | 691a870563b4fe9e014a309477fb8f9fe41b36bb (diff) | |
download | blackbird-op-linux-6830356466a57db21c7bc31bf3be4e61189e145b.tar.gz blackbird-op-linux-6830356466a57db21c7bc31bf3be4e61189e145b.zip |
UBI: Fastmap: Make ubi_refill_pools() fair
Currently ubi_refill_pools() first fills the first and then
the second one.
If only very few free PEBs are available the second pool can get
zero PEBs.
Change ubi_refill_pools() to distribute free PEBs fair between
all pools.
Signed-off-by: Richard Weinberger <richard@nod.at>
Reviewed-by: Guido Martínez <guido@vanguardiasur.com.ar>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/ubi/wl.c | 85 |
1 files changed, 47 insertions, 38 deletions
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 9f57d6b7579b..227ca641f700 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -580,59 +580,62 @@ static void return_unused_pool_pebs(struct ubi_device *ubi, } /** - * refill_wl_pool - refills all the fastmap pool used by the - * WL sub-system. + * ubi_refill_pools - refills all fastmap PEB pools. * @ubi: UBI device description object */ -static void refill_wl_pool(struct ubi_device *ubi) +void ubi_refill_pools(struct ubi_device *ubi) { + struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool; + struct ubi_fm_pool *pool = &ubi->fm_pool; struct ubi_wl_entry *e; - struct ubi_fm_pool *pool = &ubi->fm_wl_pool; + int enough; + spin_lock(&ubi->wl_lock); + + return_unused_pool_pebs(ubi, wl_pool); return_unused_pool_pebs(ubi, pool); - for (pool->size = 0; pool->size < pool->max_size; pool->size++) { - if (!ubi->free.rb_node || - (ubi->free_count - ubi->beb_rsvd_pebs < 5)) - break; + wl_pool->size = 0; + pool->size = 0; - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); - self_check_in_wl_tree(ubi, e, &ubi->free); - rb_erase(&e->u.rb, &ubi->free); - ubi->free_count--; + for (;;) { + enough = 0; + if (pool->size < pool->max_size) { + if (!ubi->free.rb_node || + (ubi->free_count - ubi->beb_rsvd_pebs < 5)) + break; - pool->pebs[pool->size] = e->pnum; - } - pool->used = 0; -} + e = wl_get_wle(ubi); + if (!e) + break; -/** - * refill_wl_user_pool - refills all the fastmap pool used by ubi_wl_get_peb. - * @ubi: UBI device description object - */ -static void refill_wl_user_pool(struct ubi_device *ubi) -{ - struct ubi_fm_pool *pool = &ubi->fm_pool; + pool->pebs[pool->size] = e->pnum; + pool->size++; + } else + enough++; - return_unused_pool_pebs(ubi, pool); + if (wl_pool->size < wl_pool->max_size) { + if (!ubi->free.rb_node || + (ubi->free_count - ubi->beb_rsvd_pebs < 5)) + break; + + e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); + self_check_in_wl_tree(ubi, e, &ubi->free); + rb_erase(&e->u.rb, &ubi->free); + ubi->free_count--; + + wl_pool->pebs[wl_pool->size] = e->pnum; + wl_pool->size++; + } else + enough++; - for (pool->size = 0; pool->size < pool->max_size; pool->size++) { - pool->pebs[pool->size] = __wl_get_peb(ubi); - if (pool->pebs[pool->size] < 0) + if (enough == 2) break; } + + wl_pool->used = 0; pool->used = 0; -} -/** - * ubi_refill_pools - refills all fastmap PEB pools. - * @ubi: UBI device description object - */ -void ubi_refill_pools(struct ubi_device *ubi) -{ - spin_lock(&ubi->wl_lock); - refill_wl_pool(ubi); - refill_wl_user_pool(ubi); spin_unlock(&ubi->wl_lock); } @@ -2002,9 +2005,15 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) dbg_wl("found %i PEBs", found_pebs); - if (ubi->fm) + if (ubi->fm) { ubi_assert(ubi->good_peb_count == \ found_pebs + ubi->fm->used_blocks); + + for (i = 0; i < ubi->fm->used_blocks; i++) { + e = ubi->fm->e[i]; + ubi->lookuptbl[e->pnum] = e; + } + } else ubi_assert(ubi->good_peb_count == found_pebs); |