Commit 82057ca
f2fs: fix to avoid invalid wait context issue
[ Upstream commit 90d5c9b ]
=============================
[ BUG: Invalid wait context ]
6.13.0-rc1 torvalds#84 Tainted: G O
-----------------------------
cat/56160 is trying to lock:
ffff888105c86648 (&cprc->stat_lock){+.+.}-{3:3}, at: update_general_status+0x32a/0x8c0 [f2fs]
other info that might help us debug this:
context-{5:5}
2 locks held by cat/56160:
#0: ffff88810a002a98 (&p->lock){+.+.}-{4:4}, at: seq_read_iter+0x56/0x4c0
#1: ffffffffa0462638 (f2fs_stat_lock){....}-{2:2}, at: stat_show+0x29/0x1020 [f2fs]
stack backtrace:
CPU: 0 UID: 0 PID: 56160 Comm: cat Tainted: G O 6.13.0-rc1 torvalds#84
Tainted: [O]=OOT_MODULE
Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
Call Trace:
<TASK>
dump_stack_lvl+0x88/0xd0
dump_stack+0x14/0x20
__lock_acquire+0x8d4/0xbb0
lock_acquire+0xd6/0x300
_raw_spin_lock+0x38/0x50
update_general_status+0x32a/0x8c0 [f2fs]
stat_show+0x50/0x1020 [f2fs]
seq_read_iter+0x116/0x4c0
seq_read+0xfa/0x130
full_proxy_read+0x66/0x90
vfs_read+0xc4/0x350
ksys_read+0x74/0xf0
__x64_sys_read+0x1d/0x20
x64_sys_call+0x17d9/0x1b80
do_syscall_64+0x68/0x130
entry_SYSCALL_64_after_hwframe+0x67/0x6f
RIP: 0033:0x7f2ca53147e2
- seq_read
- stat_show
- raw_spin_lock_irqsave(&f2fs_stat_lock, flags)
: f2fs_stat_lock is raw_spinlock_t type variable
- update_general_status
- spin_lock(&sbi->cprc_info.stat_lock);
: stat_lock is spinlock_t type variable
The root cause is the lock order is incorrect [1], we should not acquire
spinlock_t lock after raw_spinlock_t lock, as if CONFIG_PREEMPT_LOCK is
on, spinlock_t is implemented based on rtmutex, which can sleep after
holding the lock.
To fix this issue, let's use change f2fs_stat_lock lock type from
raw_spinlock_t to spinlock_t, it's safe due to:
- we don't need to use raw version of spinlock as the path is not
performance sensitive.
- we don't need to use irqsave version of spinlock as it won't be
used in irq context.
Quoted from [1]:
"Extend lockdep to validate lock wait-type context.
The current wait-types are:
LD_WAIT_FREE, /* wait free, rcu etc.. */
LD_WAIT_SPIN, /* spin loops, raw_spinlock_t etc.. */
LD_WAIT_CONFIG, /* CONFIG_PREEMPT_LOCK, spinlock_t etc.. */
LD_WAIT_SLEEP, /* sleeping locks, mutex_t etc.. */
Where lockdep validates that the current lock (the one being acquired)
fits in the current wait-context (as generated by the held stack).
This ensures that there is no attempt to acquire mutexes while holding
spinlocks, to acquire spinlocks while holding raw_spinlocks and so on. In
other words, its a more fancy might_sleep()."
[1] https://lore.kernel.org/all/[email protected]
Fixes: 98237fc ("f2fs: use spin_lock to avoid hang")
Signed-off-by: Chao Yu <[email protected]>
Signed-off-by: Jaegeuk Kim <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>1 parent f439bf1 commit 82057ca
1 file changed
+7
-10
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
439 | 439 | | |
440 | 440 | | |
441 | 441 | | |
442 | | - | |
443 | 442 | | |
444 | | - | |
| 443 | + | |
445 | 444 | | |
446 | 445 | | |
447 | 446 | | |
| |||
753 | 752 | | |
754 | 753 | | |
755 | 754 | | |
756 | | - | |
| 755 | + | |
757 | 756 | | |
758 | 757 | | |
759 | 758 | | |
| |||
765 | 764 | | |
766 | 765 | | |
767 | 766 | | |
768 | | - | |
769 | 767 | | |
770 | 768 | | |
771 | 769 | | |
| |||
817 | 815 | | |
818 | 816 | | |
819 | 817 | | |
820 | | - | |
| 818 | + | |
821 | 819 | | |
822 | | - | |
| 820 | + | |
823 | 821 | | |
824 | 822 | | |
825 | 823 | | |
826 | 824 | | |
827 | 825 | | |
828 | 826 | | |
829 | 827 | | |
830 | | - | |
831 | 828 | | |
832 | | - | |
| 829 | + | |
833 | 830 | | |
834 | | - | |
| 831 | + | |
835 | 832 | | |
836 | 833 | | |
837 | 834 | | |
| |||
0 commit comments