The patch titled Subject: locking/lockdep: dump state of percpu_rwsem upon hung up has been added to the -mm tree. Its filename is locking-lockdep-dump-state-of-percpu_rwsem-upon-hung-up.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/locking-lockdep-dump-state-of-percpu_rwsem-upon-hung-up.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/locking-lockdep-dump-state-of-percpu_rwsem-upon-hung-up.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx> Subject: locking/lockdep: dump state of percpu_rwsem upon hung up This is a temporary patch which should not go to linux.git. syzbot is hitting hung task problems at __sb_start_write() [1]. While hung tasks at __sb_start_write() suggest that filesystem was frozen, syzbot is not doing ioctl(FIFREEZE) requests. Therefore, the root cause of hung tasks is currently unknown. As a first step for debugging this problem, let's check what atomic_long_read(&sem->rw_sem.count) says when hung task is reported. Since it is impossible to reproduce this problem locally, this patch was made in order to test linux-next.git using syzbot infrastructure. [1] https://syzkaller.appspot.com/bug?id=287aa8708bc940d0ca1645223c53dd4c2d203be6 Link: http://lkml.kernel.org/r/a3cfcc9d-9d4d-7940-84c5-b8f18f5b3535@xxxxxxxxxxxxxxxxxxx Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Cc: Will Deacon <will.deacon@xxxxxxx> Cc: Dmitry Vyukov <dvyukov@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/sched.h | 1 + kernel/hung_task.c | 27 +++++++++++++++++++++++++++ kernel/locking/percpu-rwsem.c | 2 ++ 3 files changed, 30 insertions(+) diff -puN include/linux/sched.h~locking-lockdep-dump-state-of-percpu_rwsem-upon-hung-up include/linux/sched.h --- a/include/linux/sched.h~locking-lockdep-dump-state-of-percpu_rwsem-upon-hung-up +++ a/include/linux/sched.h @@ -1192,6 +1192,7 @@ struct task_struct { /* Used by LSM modules for access restriction: */ void *security; #endif + struct percpu_rw_semaphore *pcpu_rwsem_read_waiting; #ifdef CONFIG_GCC_PLUGIN_STACKLEAK unsigned long lowest_stack; diff -puN kernel/hung_task.c~locking-lockdep-dump-state-of-percpu_rwsem-upon-hung-up kernel/hung_task.c --- a/kernel/hung_task.c~locking-lockdep-dump-state-of-percpu_rwsem-upon-hung-up +++ a/kernel/hung_task.c @@ -18,6 +18,7 @@ #include <linux/utsname.h> #include <linux/sched/signal.h> #include <linux/sched/debug.h> +#include <linux/percpu-rwsem.h> #include <trace/events/sched.h> @@ -82,6 +83,31 @@ static struct notifier_block panic_block .notifier_call = hung_task_panic, }; +static void dump_percpu_rwsem_state(struct percpu_rw_semaphore *sem) +{ +#ifndef CONFIG_RWSEM_GENERIC_SPINLOCK + unsigned int sum = 0; + int cpu; + + if (!sem) + return; + pr_info("percpu_rw_semaphore(%p)\n", sem); + pr_info(" ->rw_sem.count=0x%lx\n", + atomic_long_read(&sem->rw_sem.count)); + pr_info(" ->rss.gp_state=%d\n", sem->rss.gp_state); + pr_info(" ->rss.gp_count=%d\n", sem->rss.gp_count); + pr_info(" ->rss.cb_state=%d\n", sem->rss.cb_state); + pr_info(" ->rss.gp_type=%d\n", sem->rss.gp_type); + pr_info(" ->readers_block=%d\n", sem->readers_block); + for_each_possible_cpu(cpu) + sum += per_cpu(*sem->read_count, cpu); + pr_info(" ->read_count=%d\n", sum); + pr_info(" ->list_empty(rw_sem.wait_list)=%d\n", + list_empty(&sem->rw_sem.wait_list)); + pr_info(" ->writer.task=%p\n", sem->writer.task); +#endif +} + static void check_hung_task(struct task_struct *t, unsigned long timeout) { unsigned long switch_count = t->nvcsw + t->nivcsw; @@ -130,6 +156,7 @@ static void check_hung_task(struct task_ pr_err("\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\"" " disables this message.\n"); sched_show_task(t); + dump_percpu_rwsem_state(t->pcpu_rwsem_read_waiting); hung_task_show_lock = true; } diff -puN kernel/locking/percpu-rwsem.c~locking-lockdep-dump-state-of-percpu_rwsem-upon-hung-up kernel/locking/percpu-rwsem.c --- a/kernel/locking/percpu-rwsem.c~locking-lockdep-dump-state-of-percpu_rwsem-upon-hung-up +++ a/kernel/locking/percpu-rwsem.c @@ -82,7 +82,9 @@ int __percpu_down_read(struct percpu_rw_ /* * Avoid lockdep for the down/up_read() we already have them. */ + current->pcpu_rwsem_read_waiting = sem; __down_read(&sem->rw_sem); + current->pcpu_rwsem_read_waiting = NULL; this_cpu_inc(*sem->read_count); __up_read(&sem->rw_sem); _ Patches currently in -mm which might be from penguin-kernel@xxxxxxxxxxxxxxxxxxx are locking-lockdep-dump-state-of-percpu_rwsem-upon-hung-up.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html