|
Jiri Slaby |
88bb5e |
From: ZhaoLong Wang <wangzhaolong1@huawei.com>
|
|
Jiri Slaby |
88bb5e |
Date: Sat, 4 Mar 2023 09:41:41 +0800
|
|
Jiri Slaby |
88bb5e |
Subject: [PATCH] ubi: Fix deadlock caused by recursively holding work_sem
|
|
Jiri Slaby |
88bb5e |
References: bsc#1012628
|
|
Jiri Slaby |
88bb5e |
Patch-mainline: 6.2.12
|
|
Jiri Slaby |
88bb5e |
Git-commit: f773f0a331d6c41733b17bebbc1b6cae12e016f5
|
|
Jiri Slaby |
88bb5e |
|
|
Jiri Slaby |
88bb5e |
[ Upstream commit f773f0a331d6c41733b17bebbc1b6cae12e016f5 ]
|
|
Jiri Slaby |
88bb5e |
|
|
Jiri Slaby |
88bb5e |
During the processing of the bgt, if the sync_erase() return -EBUSY
|
|
Jiri Slaby |
88bb5e |
or some other error code in __erase_worker(),schedule_erase() called
|
|
Jiri Slaby |
88bb5e |
again lead to the down_read(ubi->work_sem) hold twice and may get
|
|
Jiri Slaby |
88bb5e |
block by down_write(ubi->work_sem) in ubi_update_fastmap(),
|
|
Jiri Slaby |
88bb5e |
which cause deadlock.
|
|
Jiri Slaby |
88bb5e |
|
|
Jiri Slaby |
88bb5e |
ubi bgt other task
|
|
Jiri Slaby |
88bb5e |
do_work
|
|
Jiri Slaby |
88bb5e |
down_read(&ubi->work_sem) ubi_update_fastmap
|
|
Jiri Slaby |
88bb5e |
erase_worker # Blocked by down_read
|
|
Jiri Slaby |
88bb5e |
__erase_worker down_write(&ubi->work_sem)
|
|
Jiri Slaby |
88bb5e |
schedule_erase
|
|
Jiri Slaby |
88bb5e |
schedule_ubi_work
|
|
Jiri Slaby |
88bb5e |
down_read(&ubi->work_sem)
|
|
Jiri Slaby |
88bb5e |
|
|
Jiri Slaby |
88bb5e |
Fix this by changing input parameter @nested of the schedule_erase() to
|
|
Jiri Slaby |
88bb5e |
'true' to avoid recursively acquiring the down_read(&ubi->work_sem).
|
|
Jiri Slaby |
88bb5e |
|
|
Jiri Slaby |
88bb5e |
Also, fix the incorrect comment about @nested parameter of the
|
|
Jiri Slaby |
88bb5e |
schedule_erase() because when down_write(ubi->work_sem) is held, the
|
|
Jiri Slaby |
88bb5e |
@nested is also need be true.
|
|
Jiri Slaby |
88bb5e |
|
|
Jiri Slaby |
88bb5e |
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217093
|
|
Jiri Slaby |
88bb5e |
Fixes: 2e8f08deabbc ("ubi: Fix races around ubi_refill_pools()")
|
|
Jiri Slaby |
88bb5e |
Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
|
|
Jiri Slaby |
88bb5e |
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
|
|
Jiri Slaby |
88bb5e |
Signed-off-by: Richard Weinberger <richard@nod.at>
|
|
Jiri Slaby |
88bb5e |
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
|
Jiri Slaby |
88bb5e |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Jiri Slaby |
88bb5e |
---
|
|
Jiri Slaby |
88bb5e |
drivers/mtd/ubi/wl.c | 4 ++--
|
|
Jiri Slaby |
88bb5e |
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
Jiri Slaby |
88bb5e |
|
|
Jiri Slaby |
88bb5e |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
|
|
Jiri Slaby |
88bb5e |
index 9e143192..6049ab9e 100644
|
|
Jiri Slaby |
88bb5e |
--- a/drivers/mtd/ubi/wl.c
|
|
Jiri Slaby |
88bb5e |
+++ b/drivers/mtd/ubi/wl.c
|
|
Jiri Slaby |
88bb5e |
@@ -575,7 +575,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
|
|
Jiri Slaby |
88bb5e |
* @vol_id: the volume ID that last used this PEB
|
|
Jiri Slaby |
88bb5e |
* @lnum: the last used logical eraseblock number for the PEB
|
|
Jiri Slaby |
88bb5e |
* @torture: if the physical eraseblock has to be tortured
|
|
Jiri Slaby |
88bb5e |
- * @nested: denotes whether the work_sem is already held in read mode
|
|
Jiri Slaby |
88bb5e |
+ * @nested: denotes whether the work_sem is already held
|
|
Jiri Slaby |
88bb5e |
*
|
|
Jiri Slaby |
88bb5e |
* This function returns zero in case of success and a %-ENOMEM in case of
|
|
Jiri Slaby |
88bb5e |
* failure.
|
|
Jiri Slaby |
88bb5e |
@@ -1131,7 +1131,7 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
|
|
Jiri Slaby |
88bb5e |
int err1;
|
|
Jiri Slaby |
88bb5e |
|
|
Jiri Slaby |
88bb5e |
/* Re-schedule the LEB for erasure */
|
|
Jiri Slaby |
88bb5e |
- err1 = schedule_erase(ubi, e, vol_id, lnum, 0, false);
|
|
Jiri Slaby |
88bb5e |
+ err1 = schedule_erase(ubi, e, vol_id, lnum, 0, true);
|
|
Jiri Slaby |
88bb5e |
if (err1) {
|
|
Jiri Slaby |
88bb5e |
spin_lock(&ubi->wl_lock);
|
|
Jiri Slaby |
88bb5e |
wl_entry_destroy(ubi, e);
|
|
Jiri Slaby |
88bb5e |
--
|
|
Jiri Slaby |
88bb5e |
2.35.3
|
|
Jiri Slaby |
88bb5e |
|