• J
    perf/powerpc: Don't call perf_event_disable() from atomic context · 5aab90ce
    Jiri Olsa 提交于
    The trinity syscall fuzzer triggered following WARN() on powerpc:
    
      WARNING: CPU: 9 PID: 2998 at arch/powerpc/kernel/hw_breakpoint.c:278
      ...
      NIP [c00000000093aedc] .hw_breakpoint_handler+0x28c/0x2b0
      LR [c00000000093aed8] .hw_breakpoint_handler+0x288/0x2b0
      Call Trace:
      [c0000002f7933580] [c00000000093aed8] .hw_breakpoint_handler+0x288/0x2b0 (unreliable)
      [c0000002f7933630] [c0000000000f671c] .notifier_call_chain+0x7c/0xf0
      [c0000002f79336d0] [c0000000000f6abc] .__atomic_notifier_call_chain+0xbc/0x1c0
      [c0000002f7933780] [c0000000000f6c40] .notify_die+0x70/0xd0
      [c0000002f7933820] [c00000000001a74c] .do_break+0x4c/0x100
      [c0000002f7933920] [c0000000000089fc] handle_dabr_fault+0x14/0x48
    
    Followed by a lockdep warning:
    
      ===============================
      [ INFO: suspicious RCU usage. ]
      4.8.0-rc5+ #7 Tainted: G        W
      -------------------------------
      ./include/linux/rcupdate.h:556 Illegal context switch in RCU read-side critical section!
    
      other info that might help us debug this:
    
      rcu_scheduler_active = 1, debug_locks = 0
      2 locks held by ls/2998:
       #0:  (rcu_read_lock){......}, at: [<c0000000000f6a00>] .__atomic_notifier_call_chain+0x0/0x1c0
       #1:  (rcu_read_lock){......}, at: [<c00000000093ac50>] .hw_breakpoint_handler+0x0/0x2b0
    
      stack backtrace:
      CPU: 9 PID: 2998 Comm: ls Tainted: G        W       4.8.0-rc5+ #7
      Call Trace:
      [c0000002f7933150] [c00000000094b1f8] .dump_stack+0xe0/0x14c (unreliable)
      [c0000002f79331e0] [c00000000013c468] .lockdep_rcu_suspicious+0x138/0x180
      [c0000002f7933270] [c0000000001005d8] .___might_sleep+0x278/0x2e0
      [c0000002f7933300] [c000000000935584] .mutex_lock_nested+0x64/0x5a0
      [c0000002f7933410] [c00000000023084c] .perf_event_ctx_lock_nested+0x16c/0x380
      [c0000002f7933500] [c000000000230a80] .perf_event_disable+0x20/0x60
      [c0000002f7933580] [c00000000093aeec] .hw_breakpoint_handler+0x29c/0x2b0
      [c0000002f7933630] [c0000000000f671c] .notifier_call_chain+0x7c/0xf0
      [c0000002f79336d0] [c0000000000f6abc] .__atomic_notifier_call_chain+0xbc/0x1c0
      [c0000002f7933780] [c0000000000f6c40] .notify_die+0x70/0xd0
      [c0000002f7933820] [c00000000001a74c] .do_break+0x4c/0x100
      [c0000002f7933920] [c0000000000089fc] handle_dabr_fault+0x14/0x48
    
    While it looks like the first WARN() is probably valid, the other one is
    triggered by disabling event via perf_event_disable() from atomic context.
    
    The event is disabled here in case we were not able to emulate
    the instruction that hit the breakpoint. By disabling the event
    we unschedule the event and make sure it's not scheduled back.
    
    But we can't call perf_event_disable() from atomic context, instead
    we need to use the event's pending_disable irq_work method to disable it.
    Reported-by: NJan Stancek <jstancek@redhat.com>
    Signed-off-by: NJiri Olsa <jolsa@kernel.org>
    Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
    Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
    Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
    Cc: Huang Ying <ying.huang@intel.com>
    Cc: Jiri Olsa <jolsa@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Michael Neuling <mikey@neuling.org>
    Cc: Paul Mackerras <paulus@samba.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Link: http://lkml.kernel.org/r/20161026094824.GA21397@kravaSigned-off-by: NIngo Molnar <mingo@kernel.org>
    5aab90ce
core.c 252.6 KB