summaryrefslogtreecommitdiff
path: root/drivers/mtd/ubi/wl.c
diff options
context:
space:
mode:
authorZhihao Cheng <chengzhihao1@huawei.com>2022-05-10 15:31:25 +0300
committerRichard Weinberger <richard@nod.at>2022-05-27 17:49:07 +0300
commit14072ee33d5a2a07d735b667205f99d0a95de9f2 (patch)
tree029651d653978cf6f28c767f4f43a2b4a29b25f6 /drivers/mtd/ubi/wl.c
parentd09e9a2bddba6c48e0fddb16c4383172ac593251 (diff)
downloadlinux-14072ee33d5a2a07d735b667205f99d0a95de9f2.tar.xz
ubi: fastmap: Check wl_pool for free peb before wear leveling
UBI fetches free peb from wl_pool during wear leveling, so UBI should check wl_pool's empty status before wear leveling. Otherwise, UBI will miss wear leveling chances when free pebs are run out. 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.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index afcdacb9d0e9..55bae06cf408 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -670,7 +670,11 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
ubi_assert(!ubi->move_from && !ubi->move_to);
ubi_assert(!ubi->move_to_put);
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ if (!next_peb_for_wl(ubi) ||
+#else
if (!ubi->free.rb_node ||
+#endif
(!ubi->used.rb_node && !ubi->scrub.rb_node)) {
/*
* No free physical eraseblocks? Well, they must be waiting in
@@ -1003,8 +1007,6 @@ out_cancel:
static int ensure_wear_leveling(struct ubi_device *ubi, int nested)
{
int err = 0;
- struct ubi_wl_entry *e1;
- struct ubi_wl_entry *e2;
struct ubi_work *wrk;
spin_lock(&ubi->wl_lock);
@@ -1017,6 +1019,13 @@ static int ensure_wear_leveling(struct ubi_device *ubi, int nested)
* the WL worker has to be scheduled anyway.
*/
if (!ubi->scrub.rb_node) {
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ if (!need_wear_leveling(ubi))
+ goto out_unlock;
+#else
+ struct ubi_wl_entry *e1;
+ struct ubi_wl_entry *e2;
+
if (!ubi->used.rb_node || !ubi->free.rb_node)
/* No physical eraseblocks - no deal */
goto out_unlock;
@@ -1032,6 +1041,7 @@ static int ensure_wear_leveling(struct ubi_device *ubi, int nested)
if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD))
goto out_unlock;
+#endif
dbg_wl("schedule wear-leveling");
} else
dbg_wl("schedule scrubbing");