linux-stable/drivers/mtd
Zhihao Cheng f61b9c8760 ubi: fastmap: Fix high cpu usage of ubi_bgt by making sure wl_pool not empty
[ Upstream commit d09e9a2bdd ]

There at least 6 PEBs reserved on UBI device:
1. EBA_RESERVED_PEBS[1]
2. WL_RESERVED_PEBS[1]
3. UBI_LAYOUT_VOLUME_EBS[2]
4. MIN_FASTMAP_RESERVED_PEBS[2]

When all ubi volumes take all their PEBs, there are 3 (EBA_RESERVED_PEBS +
WL_RESERVED_PEBS + MIN_FASTMAP_RESERVED_PEBS - MIN_FASTMAP_TAKEN_PEBS[1])
free PEBs. Since commit f9c34bb529 ("ubi: Fix producing anchor PEBs")
and commit 4b68bf9a69 ("ubi: Select fastmap anchor PEBs considering
wear level rules") applied, there is only 1 (3 - FASTMAP_ANCHOR_PEBS[1] -
FASTMAP_NEXT_ANCHOR_PEBS[1]) free PEB to fill pool and wl_pool, after
filling pool, wl_pool is always empty. So, UBI could be stuck in an
infinite loop:

	ubi_thread	   system_wq
wear_leveling_worker <--------------------------------------------------
  get_peb_for_wl							|
    // fm_wl_pool, used = size = 0					|
    schedule_work(&ubi->fm_work)					|
									|
		    update_fastmap_work_fn				|
		      ubi_update_fastmap				|
			ubi_refill_pools				|
			// ubi->free_count - ubi->beb_rsvd_pebs < 5	|
			// wl_pool is not filled with any PEBs		|
			schedule_erase(old_fm_anchor)			|
			ubi_ensure_anchor_pebs				|
			  __schedule_ubi_work(wear_leveling_worker)	|
									|
__erase_worker								|
  ensure_wear_leveling							|
    __schedule_ubi_work(wear_leveling_worker) --------------------------

, which cause high cpu usage of ubi_bgt:
top - 12:10:42 up 5 min,  2 users,  load average: 1.76, 0.68, 0.27
Tasks: 123 total,   3 running,  54 sleeping,   0 stopped,   0 zombie

  PID USER PR   NI VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 1589 root 20   0   0      0      0 R  45.0  0.0   0:38.86 ubi_bgt0d
  319 root 20   0   0      0      0 I  15.2  0.0   0:15.29 kworker/0:3-eve
  371 root 20   0   0      0      0 I  14.9  0.0   0:12.85 kworker/3:3-eve
   20 root 20   0   0      0      0 I  11.3  0.0   0:05.33 kworker/1:0-eve
  202 root 20   0   0      0      0 I  11.3  0.0   0:04.93 kworker/2:3-eve

In commit 4b68bf9a69 ("ubi: Select fastmap anchor PEBs considering
wear level rules"), there are three key changes:
  1) Choose the fastmap anchor when the most free PEBs are available.
  2) Enable anchor move within the anchor area again as it is useful
     for distributing wear.
  3) Import a candidate fm anchor and check this PEB's erase count during
     wear leveling. If the wear leveling limit is exceeded, use the used
     anchor area PEB with the lowest erase count to replace it.

The anchor candidate can be removed, we can check fm_anchor PEB's erase
count during wear leveling. Fix it by:
  1) Removing 'fm_next_anchor' and check 'fm_anchor' during wear leveling.
  2) Preferentially filling one free peb into fm_wl_pool in condition of
     ubi->free_count > ubi->beb_rsvd_pebs, then try to reserve enough
     free count for fastmap non anchor pebs after the above prerequisites
     are met.
Then, there are at least 1 PEB in pool and 1 PEB in wl_pool after calling
ubi_refill_pools() with all erase works done.

Fetch a reproducer in [Link].

Fixes: 4b68bf9a69 ("ubi: Select fastmap anchor PEBs ... rules")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215407
Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2022-06-14 18:36:10 +02:00
..
chips mtd: cfi_cmdset_0002: Use chip_ready() for write on S29GL064N 2022-06-09 10:23:25 +02:00
devices mtd: mchp48l640: Add SPI ID table 2022-04-08 14:23:29 +02:00
hyperbus mtd: hyperbus: rpc-if: fix bug in rpcif_hb_remove 2022-01-27 11:03:15 +01:00
lpddr
maps mtd: fixup CFI on ixp4xx 2022-01-20 09:13:16 +01:00
nand mtd: rawnand: intel: fix possible null-ptr-deref in ebu_nand_probe() 2022-06-09 10:22:51 +02:00
parsers mtd: parsers: qcom: Fix missing free for pparts in cleanup 2022-02-23 12:03:16 +01:00
spi-nor mtd: spi-nor: core: Check written SR value in spi_nor_write_16bit_sr_and_check() 2022-06-09 10:22:51 +02:00
tests
ubi ubi: fastmap: Fix high cpu usage of ubi_bgt by making sure wl_pool not empty 2022-06-14 18:36:10 +02:00
ftl.c
inftlcore.c
inftlmount.c
Kconfig
Makefile
mtd_blkdevs.c
mtdblock.c mtdblock: warn if opened on NAND 2022-06-09 10:22:49 +02:00
mtdblock_ro.c
mtdchar.c
mtdconcat.c
mtdcore.c mtd: core: Fix a conflict between MTD and NVMEM on wp-gpios property 2022-03-02 11:48:07 +01:00
mtdcore.h
mtdoops.c
mtdpart.c mtd: Fixed breaking list in __mtd_del_partition. 2022-01-27 11:02:48 +01:00
mtdpstore.c
mtdsuper.c
mtdswap.c
nftlcore.c
nftlmount.c
rfd_ftl.c
sm_ftl.c
sm_ftl.h
ssfdc.c