Skip to content
  • Jiri Olsa's avatar
    perf/powerpc: Don't call perf_event_disable() from atomic context · 5aab90ce
    Jiri Olsa authored and Ingo Molnar's avatar Ingo Molnar committed
    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: default avatarJan Stancek <jstancek@redhat.com>
    Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
    Signed-off-by: default avatarPeter 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@krava
    
    
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    5aab90ce