diff options
| author | Kyeong Yoo <kyeong.yoo@alliedtelesis.co.nz> | 2017-07-04 16:22:38 +1200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-01-27 10:54:18 +0100 |
| commit | e3a51d6c90a8f909009342b0bb3a98f316c003b1 (patch) | |
| tree | 0a4bd33ee84916fa7bdd5c1cdac5bd41c696cfbf /include | |
| parent | e35cb5b122fcdce50690916a241e2ef4cef736a7 (diff) | |
jffs2: GC deadlock reading a page that is used in jffs2_write_begin()
[ Upstream commit aa39cc675799bc92da153af9a13d6f969c348e82 ]
GC task can deadlock in read_cache_page() because it may attempt
to release a page that is actually allocated by another task in
jffs2_write_begin().
The reason is that in jffs2_write_begin() there is a small window
a cache page is allocated for use but not set Uptodate yet.
This ends up with a deadlock between two tasks:
1) A task (e.g. file copy)
- jffs2_write_begin() locks a cache page
- jffs2_write_end() tries to lock "alloc_sem" from
jffs2_reserve_space() <-- STUCK
2) GC task (jffs2_gcd_mtd3)
- jffs2_garbage_collect_pass() locks "alloc_sem"
- try to lock the same cache page in read_cache_page() <-- STUCK
So to avoid this deadlock, hold "alloc_sem" in jffs2_write_begin()
while reading data in a cache page.
Signed-off-by: Kyeong Yoo <kyeong.yoo@alliedtelesis.co.nz>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include')
0 files changed, 0 insertions, 0 deletions
