This pull request contains a single change for UBI:
- Select fastmap anchor PEBs considering wear level rules -----BEGIN PGP SIGNATURE----- iQJKBAABCAA0FiEEdgfidid8lnn52cLTZvlZhesYu8EFAl7f99wWHHJpY2hhcmRA c2lnbWEtc3Rhci5hdAAKCRBm+VmF6xi7wVI1D/sHx7bYa7Blo8/q1np5/eG4GYwA pC3CMy1/QAXlCMovBuZlqyBXHK3ENRnnhVuCMIaanfL8nTBWsVfpbiJORnUaBBBR 2zrR+jovIwgZrmhn3Xuq8v5yhoASb7hP9ToNQZzD+R77OvjK/IpU6S63xOQf0017 OaI3IdX36dQ8RCUg9yxpn11doTf1UyFdA6amMohe8owuYsPMd29Lt9r3K7swqzyJ jJ0XyzCRy/3VPgrtUZFfWXJrSgonDX4klD3L+hPHfjrby2QcWa0YdJf3pKgY0IlU 72gxXsSYq3jIkLPOA8/V89X0vPUjiiYyf7kYj82anIgFunAfP95vGweT6l06XR+i MyeWOgPQZBhbPN1hWJTILEKZLvCNflPB0jaZ9zRbqT79kV0mzH0Osd7nCpiX3JTq OFf9B6jV4ksp24g08d/64qbItDbXBiytyDjtrKZ7y2qsu3sEmvQ6V5DEnoeRAx/E L/dYaGJVrQlr5UbI3lKJI0voEDERuIcZ3fD6/1YiRJSucgAZmKe4mpyzWIA4Y5dO LPqoQAkpTSAOXwwKzBGBYfoHnZhG+jnkOqc6zfsmLzuDmhOzKsmtbIX0mHP+GK3N JJy2tXF1xppLAc798C81Njn4bpZMSeDT6+6Sfh24xSoGPYlvW40UHHI/yuaQEcK9 pEfRulAxE4ez2TWVuw== =UtI2 -----END PGP SIGNATURE----- Merge tag 'for-linus-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs Pull UBI update from Richard Weinberger: "This contains a single change for UBI: - Select fastmap anchor PEBs considering wear level rules" * tag 'for-linus-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs: ubi: Select fastmap anchor PEBs considering wear level rules
This commit is contained in:
commit
0e083da7c8
|
@ -116,6 +116,21 @@ void ubi_refill_pools(struct ubi_device *ubi)
|
||||||
wl_pool->size = 0;
|
wl_pool->size = 0;
|
||||||
pool->size = 0;
|
pool->size = 0;
|
||||||
|
|
||||||
|
if (ubi->fm_anchor) {
|
||||||
|
wl_tree_add(ubi->fm_anchor, &ubi->free);
|
||||||
|
ubi->free_count++;
|
||||||
|
}
|
||||||
|
if (ubi->fm_next_anchor) {
|
||||||
|
wl_tree_add(ubi->fm_next_anchor, &ubi->free);
|
||||||
|
ubi->free_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All available PEBs are in ubi->free, now is the time to get
|
||||||
|
* the best anchor PEBs.
|
||||||
|
*/
|
||||||
|
ubi->fm_anchor = ubi_wl_get_fm_peb(ubi, 1);
|
||||||
|
ubi->fm_next_anchor = ubi_wl_get_fm_peb(ubi, 1);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
enough = 0;
|
enough = 0;
|
||||||
if (pool->size < pool->max_size) {
|
if (pool->size < pool->max_size) {
|
||||||
|
@ -271,26 +286,20 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
|
||||||
int ubi_ensure_anchor_pebs(struct ubi_device *ubi)
|
int ubi_ensure_anchor_pebs(struct ubi_device *ubi)
|
||||||
{
|
{
|
||||||
struct ubi_work *wrk;
|
struct ubi_work *wrk;
|
||||||
struct ubi_wl_entry *anchor;
|
|
||||||
|
|
||||||
spin_lock(&ubi->wl_lock);
|
spin_lock(&ubi->wl_lock);
|
||||||
|
|
||||||
/* Do we already have an anchor? */
|
/* Do we have a next anchor? */
|
||||||
if (ubi->fm_anchor) {
|
if (!ubi->fm_next_anchor) {
|
||||||
spin_unlock(&ubi->wl_lock);
|
ubi->fm_next_anchor = ubi_wl_get_fm_peb(ubi, 1);
|
||||||
return 0;
|
if (!ubi->fm_next_anchor)
|
||||||
}
|
/* Tell wear leveling to produce a new anchor PEB */
|
||||||
|
|
||||||
/* See if we can find an anchor PEB on the list of free PEBs */
|
|
||||||
anchor = ubi_wl_get_fm_peb(ubi, 1);
|
|
||||||
if (anchor) {
|
|
||||||
ubi->fm_anchor = anchor;
|
|
||||||
spin_unlock(&ubi->wl_lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No luck, trigger wear leveling to produce a new anchor PEB */
|
|
||||||
ubi->fm_do_produce_anchor = 1;
|
ubi->fm_do_produce_anchor = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do wear leveling to get a new anchor PEB or check the
|
||||||
|
* existing next anchor candidate.
|
||||||
|
*/
|
||||||
if (ubi->wl_scheduled) {
|
if (ubi->wl_scheduled) {
|
||||||
spin_unlock(&ubi->wl_lock);
|
spin_unlock(&ubi->wl_lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1220,6 +1220,17 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
|
||||||
fm_pos += sizeof(*fec);
|
fm_pos += sizeof(*fec);
|
||||||
ubi_assert(fm_pos <= ubi->fm_size);
|
ubi_assert(fm_pos <= ubi->fm_size);
|
||||||
}
|
}
|
||||||
|
if (ubi->fm_next_anchor) {
|
||||||
|
fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
|
||||||
|
|
||||||
|
fec->pnum = cpu_to_be32(ubi->fm_next_anchor->pnum);
|
||||||
|
set_seen(ubi, ubi->fm_next_anchor->pnum, seen_pebs);
|
||||||
|
fec->ec = cpu_to_be32(ubi->fm_next_anchor->ec);
|
||||||
|
|
||||||
|
free_peb_count++;
|
||||||
|
fm_pos += sizeof(*fec);
|
||||||
|
ubi_assert(fm_pos <= ubi->fm_size);
|
||||||
|
}
|
||||||
fmh->free_peb_count = cpu_to_be32(free_peb_count);
|
fmh->free_peb_count = cpu_to_be32(free_peb_count);
|
||||||
|
|
||||||
ubi_for_each_used_peb(ubi, wl_e, tmp_rb) {
|
ubi_for_each_used_peb(ubi, wl_e, tmp_rb) {
|
||||||
|
|
|
@ -491,7 +491,8 @@ struct ubi_debug_info {
|
||||||
* @fm_work: fastmap work queue
|
* @fm_work: fastmap work queue
|
||||||
* @fm_work_scheduled: non-zero if fastmap work was scheduled
|
* @fm_work_scheduled: non-zero if fastmap work was scheduled
|
||||||
* @fast_attach: non-zero if UBI was attached by fastmap
|
* @fast_attach: non-zero if UBI was attached by fastmap
|
||||||
* @fm_anchor: The next anchor PEB to use for fastmap
|
* @fm_anchor: The new anchor PEB used during fastmap update
|
||||||
|
* @fm_next_anchor: An anchor PEB candidate for the next time fastmap is updated
|
||||||
* @fm_do_produce_anchor: If true produce an anchor PEB in wl
|
* @fm_do_produce_anchor: If true produce an anchor PEB in wl
|
||||||
*
|
*
|
||||||
* @used: RB-tree of used physical eraseblocks
|
* @used: RB-tree of used physical eraseblocks
|
||||||
|
@ -602,6 +603,7 @@ struct ubi_device {
|
||||||
int fm_work_scheduled;
|
int fm_work_scheduled;
|
||||||
int fast_attach;
|
int fast_attach;
|
||||||
struct ubi_wl_entry *fm_anchor;
|
struct ubi_wl_entry *fm_anchor;
|
||||||
|
struct ubi_wl_entry *fm_next_anchor;
|
||||||
int fm_do_produce_anchor;
|
int fm_do_produce_anchor;
|
||||||
|
|
||||||
/* Wear-leveling sub-system's stuff */
|
/* Wear-leveling sub-system's stuff */
|
||||||
|
|
|
@ -687,20 +687,27 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MTD_UBI_FASTMAP
|
#ifdef CONFIG_MTD_UBI_FASTMAP
|
||||||
if (ubi->fm_do_produce_anchor) {
|
|
||||||
e1 = find_anchor_wl_entry(&ubi->used);
|
e1 = find_anchor_wl_entry(&ubi->used);
|
||||||
|
if (e1 && ubi->fm_next_anchor &&
|
||||||
|
(ubi->fm_next_anchor->ec - e1->ec >= UBI_WL_THRESHOLD)) {
|
||||||
|
ubi->fm_do_produce_anchor = 1;
|
||||||
|
/* fm_next_anchor is no longer considered a good anchor
|
||||||
|
* candidate.
|
||||||
|
* NULL assignment also prevents multiple wear level checks
|
||||||
|
* of this PEB.
|
||||||
|
*/
|
||||||
|
wl_tree_add(ubi->fm_next_anchor, &ubi->free);
|
||||||
|
ubi->fm_next_anchor = NULL;
|
||||||
|
ubi->free_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ubi->fm_do_produce_anchor) {
|
||||||
if (!e1)
|
if (!e1)
|
||||||
goto out_cancel;
|
goto out_cancel;
|
||||||
e2 = get_peb_for_wl(ubi);
|
e2 = get_peb_for_wl(ubi);
|
||||||
if (!e2)
|
if (!e2)
|
||||||
goto out_cancel;
|
goto out_cancel;
|
||||||
|
|
||||||
/*
|
|
||||||
* Anchor move within the anchor area is useless.
|
|
||||||
*/
|
|
||||||
if (e2->pnum < UBI_FM_MAX_START)
|
|
||||||
goto out_cancel;
|
|
||||||
|
|
||||||
self_check_in_wl_tree(ubi, e1, &ubi->used);
|
self_check_in_wl_tree(ubi, e1, &ubi->used);
|
||||||
rb_erase(&e1->u.rb, &ubi->used);
|
rb_erase(&e1->u.rb, &ubi->used);
|
||||||
dbg_wl("anchor-move PEB %d to PEB %d", e1->pnum, e2->pnum);
|
dbg_wl("anchor-move PEB %d to PEB %d", e1->pnum, e2->pnum);
|
||||||
|
@ -1079,8 +1086,11 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
|
||||||
if (!err) {
|
if (!err) {
|
||||||
spin_lock(&ubi->wl_lock);
|
spin_lock(&ubi->wl_lock);
|
||||||
|
|
||||||
if (!ubi->fm_anchor && e->pnum < UBI_FM_MAX_START) {
|
if (!ubi->fm_next_anchor && e->pnum < UBI_FM_MAX_START) {
|
||||||
ubi->fm_anchor = e;
|
/* Abort anchor production, if needed it will be
|
||||||
|
* enabled again in the wear leveling started below.
|
||||||
|
*/
|
||||||
|
ubi->fm_next_anchor = e;
|
||||||
ubi->fm_do_produce_anchor = 0;
|
ubi->fm_do_produce_anchor = 0;
|
||||||
} else {
|
} else {
|
||||||
wl_tree_add(e, &ubi->free);
|
wl_tree_add(e, &ubi->free);
|
||||||
|
|
Loading…
Reference in New Issue