]> Git Repo - linux.git/commitdiff
ubi: fastmap: may_reserve_for_fm: Don't reserve PEB if fm_anchor exists
authorZhihao Cheng <[email protected]>
Mon, 28 Aug 2023 06:38:41 +0000 (14:38 +0800)
committerRichard Weinberger <[email protected]>
Sat, 28 Oct 2023 20:49:14 +0000 (22:49 +0200)
This is the part 1 to fix cyclically reusing single fastmap data PEBs.

After running fsstress on UBIFS for a while, UBI (16384 blocks, fastmap
takes 2 blocks) has an erase block(PEB: 8031) with big erase counter
greater than any other pebs:

=========================================================
from              to     count      min      avg      max
---------------------------------------------------------
0        ..        9:        0        0        0        0
10       ..       99:      532       84       92       99
100      ..      999:    15787      100      147      229
1000     ..     9999:       64     4699     4765     4826
10000    ..    99999:        0        0        0        0
100000   ..      inf:        1   272935   272935   272935
---------------------------------------------------------
Total               :    16384       84      180   272935

Not like fm_anchor, there is no candidate PEBs for fastmap data area,
so old fastmap data pebs will be reused after all free pebs are filled
into pool/wl_pool:
ubi_update_fastmap
 for (i = 1; i < new_fm->used_blocks; i++)
  erase_block(ubi, old_fm->e[i]->pnum)
  new_fm->e[i] = old_fm->e[i]

According to wear leveling algorithm, UBI selects one small erase
counter PEB from ubi->used and one big erase counter PEB from wl_pool,
the reused fastmap data PEB is not in these trees. UBI won't schedule
this PEB for wl even it is in ubi->used because wl algorithm expects
small erase counter for used PEB.

Don't reserve PEB for fastmap in may_reserve_for_fm() if fm_anchor
already exists. Otherwise, when UBI is running out of free PEBs,
the only one free PEB (pnum < 64) will be skipped and fastmap data
will be written on the same old PEB.

Fixes: dbb7d2a88d2a ("UBI: Add fastmap core")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217787
Signed-off-by: Zhihao Cheng <[email protected]>
Signed-off-by: Richard Weinberger <[email protected]>
drivers/mtd/ubi/fastmap-wl.c
drivers/mtd/ubi/wl.c

index 7c4cfd80da317f9aee672ede40c2a1fae6231d5d..490514da1e00acaa928b18b5e1a533833a764253 100644 (file)
@@ -521,7 +521,7 @@ static void ubi_fastmap_close(struct ubi_device *ubi)
 static struct ubi_wl_entry *may_reserve_for_fm(struct ubi_device *ubi,
                                           struct ubi_wl_entry *e,
                                           struct rb_root *root) {
-       if (e && !ubi->fm_disabled && !ubi->fm &&
+       if (e && !ubi->fm_disabled && !ubi->fm && !ubi->fm_anchor &&
            e->pnum < UBI_FM_MAX_START)
                e = rb_entry(rb_next(root->rb_node),
                             struct ubi_wl_entry, u.rb);
index 14edb65ce6a68aec01fcb109bc7bec98ca3e05bc..40a1c306b8affc16bcbb58c1642634454dbe0174 100644 (file)
@@ -367,9 +367,12 @@ static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi,
        if (last->ec - first->ec < WL_FREE_MAX_DIFF) {
                e = rb_entry(root->rb_node, struct ubi_wl_entry, u.rb);
 
-               /* 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 no fastmap has been written and fm_anchor is not
+                * reserved 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.
+                */
                e = may_reserve_for_fm(ubi, e, root);
        } else
                e = find_wl_entry(ubi, root, WL_FREE_MAX_DIFF/2);
This page took 0.063767 seconds and 4 git commands to generate.