diff options
author | Zhihao Cheng <chengzhihao1@huawei.com> | 2023-08-28 09:38:39 +0300 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2023-10-28 23:43:40 +0300 |
commit | a2ea69dac674df0fba59c66146a21145108a85ed (patch) | |
tree | 9a6b2e6b4f5c30fa4b653034fa78d488004f539b /drivers/mtd/ubi/wl.c | |
parent | 8ff4e620ac93a5d332735e4f5a4ff31d80682b9a (diff) | |
download | linux-a2ea69dac674df0fba59c66146a21145108a85ed.tar.xz |
ubi: fastmap: Wait until there are enough free PEBs before filling pools
Wait until there are enough free PEBs before filling pool/wl_pool,
sometimes erase_worker is not scheduled in time, which causes two
situations:
A. There are few PEBs filled in pool, which makes ubi_update_fastmap
is frequently called and leads first 64 PEBs are erased more times
than other PEBs. So waiting free PEBs before filling pool reduces
fastmap updating frequency and prolongs flash service life.
B. In situation that space is nearly running out, ubi_refill_pools()
cannot make sure pool and wl_pool are filled with free PEBs, caused
by the delay of erase_worker. After this patch applied, there must
exist free PEBs in pool after one call of ubi_update_fastmap.
Besides, this patch is a preparetion for fixing large erase counter in
fastmap data block and fixing lapsed wear leveling for first 64 PEBs.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217787
Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'drivers/mtd/ubi/wl.c')
-rw-r--r-- | drivers/mtd/ubi/wl.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 0c78e09d7960..14edb65ce6a6 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -181,11 +181,13 @@ static void wl_entry_destroy(struct ubi_device *ubi, struct ubi_wl_entry *e) /** * do_work - do one pending work. * @ubi: UBI device description object + * @executed: whether there is one work is executed * * This function returns zero in case of success and a negative error code in - * case of failure. + * case of failure. If @executed is not NULL and there is one work executed, + * @executed is set as %1, otherwise @executed is set as %0. */ -static int do_work(struct ubi_device *ubi) +static int do_work(struct ubi_device *ubi, int *executed) { int err; struct ubi_work *wrk; @@ -203,9 +205,13 @@ static int do_work(struct ubi_device *ubi) if (list_empty(&ubi->works)) { spin_unlock(&ubi->wl_lock); up_read(&ubi->work_sem); + if (executed) + *executed = 0; return 0; } + if (executed) + *executed = 1; wrk = list_entry(ubi->works.next, struct ubi_work, list); list_del(&wrk->list); ubi->works_count -= 1; @@ -1685,7 +1691,7 @@ int ubi_thread(void *u) } spin_unlock(&ubi->wl_lock); - err = do_work(ubi); + err = do_work(ubi, NULL); if (err) { ubi_err(ubi, "%s: work failed with error code %d", ubi->bgt_name, err); @@ -2096,7 +2102,7 @@ static int produce_free_peb(struct ubi_device *ubi) spin_unlock(&ubi->wl_lock); dbg_wl("do one work synchronously"); - err = do_work(ubi); + err = do_work(ubi, NULL); spin_lock(&ubi->wl_lock); if (err) |