diff options
author | Zhihao Cheng <[email protected]> | 2022-07-13 21:00:29 +0800 |
---|---|---|
committer | akpm <[email protected]> | 2022-07-17 17:31:43 -0700 |
commit | d919a1e79bac890421537cf02ae773007bf55e6b (patch) | |
tree | 28857f4f57688ffffcbf55ad87b824894f3fcfdb /scripts/gdb/linux/modules.py | |
parent | 7ffe4e90a061a2f612b3b8c29b583ec3b707781f (diff) |
proc: fix a dentry lock race between release_task and lookup
Commit 7bc3e6e55acf06 ("proc: Use a list of inodes to flush from proc")
moved proc_flush_task() behind __exit_signal(). Then, process systemd can
take long period high cpu usage during releasing task in following
concurrent processes:
systemd ps
kernel_waitid stat(/proc/tgid)
do_wait filename_lookup
wait_consider_task lookup_fast
release_task
__exit_signal
__unhash_process
detach_pid
__change_pid // remove task->pid_links
d_revalidate -> pid_revalidate // 0
d_invalidate(/proc/tgid)
shrink_dcache_parent(/proc/tgid)
d_walk(/proc/tgid)
spin_lock_nested(/proc/tgid/fd)
// iterating opened fd
proc_flush_pid |
d_invalidate (/proc/tgid/fd) |
shrink_dcache_parent(/proc/tgid/fd) |
shrink_dentry_list(subdirs) ↓
shrink_lock_dentry(/proc/tgid/fd) --> race on dentry lock
Function d_invalidate() will remove dentry from hash firstly, but why does
proc_flush_pid() process dentry '/proc/tgid/fd' before dentry
'/proc/tgid'? That's because proc_pid_make_inode() adds proc inode in
reverse order by invoking hlist_add_head_rcu(). But proc should not add
any inodes under '/proc/tgid' except '/proc/tgid/task/pid', fix it by
adding inode into 'pid->inodes' only if the inode is /proc/tgid or
/proc/tgid/task/pid.
Performance regression:
Create 200 tasks, each task open one file for 50,000 times. Kill all
tasks when opened files exceed 10,000,000 (cat /proc/sys/fs/file-nr).
Before fix:
$ time killall -wq aa
real 4m40.946s # During this period, we can see 'ps' and 'systemd'
taking high cpu usage.
After fix:
$ time killall -wq aa
real 1m20.732s # During this period, we can see 'systemd' taking
high cpu usage.
Link: https://lkml.kernel.org/r/[email protected]
Fixes: 7bc3e6e55acf06 ("proc: Use a list of inodes to flush from proc")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216054
Signed-off-by: Zhihao Cheng <[email protected]>
Signed-off-by: Zhang Yi <[email protected]>
Suggested-by: Brian Foster <[email protected]>
Reviewed-by: Brian Foster <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Alexey Dobriyan <[email protected]>
Cc: Eric Biederman <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Baoquan He <[email protected]>
Cc: Kalesh Singh <[email protected]>
Cc: Yu Kuai <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Diffstat (limited to 'scripts/gdb/linux/modules.py')
0 files changed, 0 insertions, 0 deletions