The reproducer involves running test programs on multiple processors separately, in order to enter blkdev_ioctl() and ultimately reach blk_trace_ioctl() through two different paths, triggering an AA deadlock.
CPU0 CPU1 --- --- mutex_lock(&q->debugfs_mutex) mutex_lock(&q->debugfs_mutex) mutex_lock(&q->debugfs_mutex) mutex_lock(&q->debugfs_mutex) The first path: blkdev_ioctl()-> blk_trace_ioctl()-> mutex_lock(&q->debugfs_mutex) The second path: blkdev_ioctl()-> blkdev_common_ioctl()-> blk_trace_ioctl()-> mutex_lock(&q->debugfs_mutex) The solution I have proposed is to exit blk_trace_ioctl() to avoid AA locks if a task has already obtained debugfs_mutex. Fixes: 0d345996e4cb ("x86/kernel: increase kcov coverage under arch/x86/kernel folder") Reported-and-tested-by: syzbot+ed812ed461471ab17...@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis <eada...@qq.com> --- kernel/trace/blktrace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 54ade89a1ad2..34e5bce42b1e 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -735,7 +735,8 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) int ret, start = 0; char b[BDEVNAME_SIZE]; - mutex_lock(&q->debugfs_mutex); + if (!mutex_trylock(&q->debugfs_mutex)) + return -EBUSY; switch (cmd) { case BLKTRACESETUP: -- 2.43.0