mirror of https://github.com/torvalds/linux.git
On the irq exit path, tick_nohz_irq_exit() may raise a softirq, which action leads to the wake up path and select_task_rq_fair() that makes use of rcu to iterate the domains. This is an illegal use of RCU because we may be in RCU extended quiescent state if we interrupted an RCU-idle window in the idle loop: [ 132.978883] =============================== [ 132.978883] [ INFO: suspicious RCU usage. ] [ 132.978883] ------------------------------- [ 132.978883] kernel/sched_fair.c:1707 suspicious rcu_dereference_check() usage! [ 132.978883] [ 132.978883] other info that might help us debug this: [ 132.978883] [ 132.978883] [ 132.978883] rcu_scheduler_active = 1, debug_locks = 0 [ 132.978883] RCU used illegally from extended quiescent state! [ 132.978883] 2 locks held by swapper/0: [ 132.978883] #0: (&p->pi_lock){-.-.-.}, at: [<ffffffff8105a729>] try_to_wake_up+0x39/0x2f0 [ 132.978883] #1: (rcu_read_lock){.+.+..}, at: [<ffffffff8105556a>] select_task_rq_fair+0x6a/0xec0 [ 132.978883] [ 132.978883] stack backtrace: [ 132.978883] Pid: 0, comm: swapper Tainted: G W 3.0.0+ #178 [ 132.978883] Call Trace: [ 132.978883] <IRQ> [<ffffffff810a01f6>] lockdep_rcu_suspicious+0xe6/0x100 [ 132.978883] [<ffffffff81055c49>] select_task_rq_fair+0x749/0xec0 [ 132.978883] [<ffffffff8105556a>] ? select_task_rq_fair+0x6a/0xec0 [ 132.978883] [<ffffffff812fe494>] ? do_raw_spin_lock+0x54/0x150 [ 132.978883] [<ffffffff810a1f2d>] ? trace_hardirqs_on+0xd/0x10 [ 132.978883] [<ffffffff8105a7c3>] try_to_wake_up+0xd3/0x2f0 [ 132.978883] [<ffffffff81094f98>] ? ktime_get+0x68/0xf0 [ 132.978883] [<ffffffff8105aa35>] wake_up_process+0x15/0x20 [ 132.978883] [<ffffffff81069dd5>] raise_softirq_irqoff+0x65/0x110 [ 132.978883] [<ffffffff8108eb65>] __hrtimer_start_range_ns+0x415/0x5a0 [ 132.978883] [<ffffffff812fe3ee>] ? do_raw_spin_unlock+0x5e/0xb0 [ 132.978883] [<ffffffff8108ed08>] hrtimer_start+0x18/0x20 [ 132.978883] [<ffffffff8109c9c3>] tick_nohz_stop_sched_tick+0x393/0x450 [ 132.978883] [<ffffffff810694f2>] irq_exit+0xd2/0x100 [ 132.978883] [<ffffffff81829e96>] do_IRQ+0x66/0xe0 [ 132.978883] [<ffffffff81820d53>] common_interrupt+0x13/0x13 [ 132.978883] <EOI> [<ffffffff8103434b>] ? native_safe_halt+0xb/0x10 [ 132.978883] [<ffffffff810a1f2d>] ? trace_hardirqs_on+0xd/0x10 [ 132.978883] [<ffffffff810144ea>] default_idle+0xba/0x370 [ 132.978883] [<ffffffff810147fe>] amd_e400_idle+0x5e/0x130 [ 132.978883] [<ffffffff8100a9f6>] cpu_idle+0xb6/0x120 [ 132.978883] [<ffffffff817f217f>] rest_init+0xef/0x150 [ 132.978883] [<ffffffff817f20e2>] ? rest_init+0x52/0x150 [ 132.978883] [<ffffffff81ed9cf3>] start_kernel+0x3da/0x3e5 [ 132.978883] [<ffffffff81ed9346>] x86_64_start_reservations+0x131/0x135 [ 132.978883] [<ffffffff81ed944d>] x86_64_start_kernel+0x103/0x112 Fix this by calling rcu_idle_enter() after tick_nohz_irq_exit(). Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org> |
||
|---|---|---|
| .. | ||
| debug | ||
| events | ||
| gcov | ||
| irq | ||
| power | ||
| time | ||
| trace | ||
| .gitignore | ||
| Kconfig.freezer | ||
| Kconfig.hz | ||
| Kconfig.locks | ||
| Kconfig.preempt | ||
| Makefile | ||
| acct.c | ||
| async.c | ||
| audit.c | ||
| audit.h | ||
| audit_tree.c | ||
| audit_watch.c | ||
| auditfilter.c | ||
| auditsc.c | ||
| backtracetest.c | ||
| bounds.c | ||
| capability.c | ||
| cgroup.c | ||
| cgroup_freezer.c | ||
| compat.c | ||
| configs.c | ||
| cpu.c | ||
| cpu_pm.c | ||
| cpuset.c | ||
| crash_dump.c | ||
| cred.c | ||
| delayacct.c | ||
| dma.c | ||
| elfcore.c | ||
| exec_domain.c | ||
| exit.c | ||
| extable.c | ||
| fork.c | ||
| freezer.c | ||
| futex.c | ||
| futex_compat.c | ||
| groups.c | ||
| hrtimer.c | ||
| hung_task.c | ||
| irq_work.c | ||
| itimer.c | ||
| jump_label.c | ||
| kallsyms.c | ||
| kexec.c | ||
| kfifo.c | ||
| kmod.c | ||
| kprobes.c | ||
| ksysfs.c | ||
| kthread.c | ||
| latencytop.c | ||
| lockdep.c | ||
| lockdep_internals.h | ||
| lockdep_proc.c | ||
| lockdep_states.h | ||
| module.c | ||
| mutex-debug.c | ||
| mutex-debug.h | ||
| mutex.c | ||
| mutex.h | ||
| notifier.c | ||
| nsproxy.c | ||
| padata.c | ||
| panic.c | ||
| params.c | ||
| pid.c | ||
| pid_namespace.c | ||
| posix-cpu-timers.c | ||
| posix-timers.c | ||
| printk.c | ||
| profile.c | ||
| ptrace.c | ||
| range.c | ||
| rcu.h | ||
| rcupdate.c | ||
| rcutiny.c | ||
| rcutiny_plugin.h | ||
| rcutorture.c | ||
| rcutree.c | ||
| rcutree.h | ||
| rcutree_plugin.h | ||
| rcutree_trace.c | ||
| relay.c | ||
| res_counter.c | ||
| resource.c | ||
| rtmutex-debug.c | ||
| rtmutex-debug.h | ||
| rtmutex-tester.c | ||
| rtmutex.c | ||
| rtmutex.h | ||
| rtmutex_common.h | ||
| rwsem.c | ||
| sched.c | ||
| sched_autogroup.c | ||
| sched_autogroup.h | ||
| sched_clock.c | ||
| sched_cpupri.c | ||
| sched_cpupri.h | ||
| sched_debug.c | ||
| sched_fair.c | ||
| sched_features.h | ||
| sched_idletask.c | ||
| sched_rt.c | ||
| sched_stats.h | ||
| sched_stoptask.c | ||
| seccomp.c | ||
| semaphore.c | ||
| signal.c | ||
| smp.c | ||
| softirq.c | ||
| spinlock.c | ||
| srcu.c | ||
| stacktrace.c | ||
| stop_machine.c | ||
| sys.c | ||
| sys_ni.c | ||
| sysctl.c | ||
| sysctl_binary.c | ||
| sysctl_check.c | ||
| taskstats.c | ||
| test_kprobes.c | ||
| time.c | ||
| timeconst.pl | ||
| timer.c | ||
| tracepoint.c | ||
| tsacct.c | ||
| uid16.c | ||
| up.c | ||
| user-return-notifier.c | ||
| user.c | ||
| user_namespace.c | ||
| utsname.c | ||
| utsname_sysctl.c | ||
| wait.c | ||
| watchdog.c | ||
| workqueue.c | ||
| workqueue_sched.h | ||