Skip to content
  • Will Deacon's avatar
    perf/core: Use this_cpu_ptr() when stopping AUX events · 8b6a3fe8
    Will Deacon authored
    
    
    When tearing down an AUX buf for an event via perf_mmap_close(),
    __perf_event_output_stop() is called on the event's CPU to ensure that
    trace generation is halted before the process of unmapping and
    freeing the buffer pages begins.
    
    The callback is performed via cpu_function_call(), which ensures that it
    runs with interrupts disabled and is therefore not preemptible.
    Unfortunately, the current code grabs the per-cpu context pointer using
    get_cpu_ptr(), which unnecessarily disables preemption and doesn't pair
    the call with put_cpu_ptr(), leading to a preempt_count() imbalance and
    a BUG when freeing the AUX buffer later on:
    
      WARNING: CPU: 1 PID: 2249 at kernel/events/ring_buffer.c:539 __rb_free_aux+0x10c/0x120
      Modules linked in:
      [...]
      Call Trace:
       [<ffffffff813379dd>] dump_stack+0x4f/0x72
       [<ffffffff81059ff6>] __warn+0xc6/0xe0
       [<ffffffff8105a0c8>] warn_slowpath_null+0x18/0x20
       [<ffffffff8112761c>] __rb_free_aux+0x10c/0x120
       [<ffffffff81128163>] rb_free_aux+0x13/0x20
       [<ffffffff8112515e>] perf_mmap_close+0x29e/0x2f0
       [<ffffffff8111da30>] ? perf_iterate_ctx+0xe0/0xe0
       [<ffffffff8115f685>] remove_vma+0x25/0x60
       [<ffffffff81161796>] exit_mmap+0x106/0x140
       [<ffffffff8105725c>] mmput+0x1c/0xd0
       [<ffffffff8105cac3>] do_exit+0x253/0xbf0
       [<ffffffff8105e32e>] do_group_exit+0x3e/0xb0
       [<ffffffff81068d49>] get_signal+0x249/0x640
       [<ffffffff8101c273>] do_signal+0x23/0x640
       [<ffffffff81905f42>] ? _raw_write_unlock_irq+0x12/0x30
       [<ffffffff81905f69>] ? _raw_spin_unlock_irq+0x9/0x10
       [<ffffffff81901896>] ? __schedule+0x2c6/0x710
       [<ffffffff810022a4>] exit_to_usermode_loop+0x74/0x90
       [<ffffffff81002a56>] prepare_exit_to_usermode+0x26/0x30
       [<ffffffff81906d1b>] retint_user+0x8/0x10
    
    This patch uses this_cpu_ptr() instead of get_cpu_ptr(), since preemption is
    already disabled by the caller.
    
    Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
    Reviewed-by: default avatarAlexander Shishkin <alexander.shishkin@linux.intel.com>
    Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Vince Weaver <vincent.weaver@maine.edu>
    Fixes: 95ff4ca2 ("perf/core: Free AUX pages in unmap path")
    Link: http://lkml.kernel.org/r/20160824091905.GA16944@arm.com
    
    
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    8b6a3fe8