Patch "perf/core: Use this_cpu_ptr() when stopping AUX events" has been added to the 4.7-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
perf/core: Use this_cpu_ptr() when stopping AUX events
to the 4.7-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
perf-core-use-this_cpu_ptr-when-stopping-aux-events.patch
and it can be found in the queue-4.7 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
8b6a3fe8fab97716990a3abde1a01fb5a34552a3Mon Sep 17 00:00:00 2001
From: Will Deacon <[email protected]>
Date: Wed, 24 Aug 2016 10:07:14 +0100
Subject: perf/core: Use this_cpu_ptr() when stopping AUX events
From: Will Deacon <[email protected]>
commit 8b6a3fe8fab97716990a3abde1a01fb5a34552a3 upstream.
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.
--- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/core.c +1 -1
@@ -6064,7 +6064,7 @@ static int __perf_pmu_output_stop(void * {struct perf_event *event = info;struct pmu *pmu = event->pmu; -struct perf_cpu_context *cpuctx =get_cpu_ptr (pmu->pmu_cpu_context); +struct perf_cpu_context *cpuctx =this_cpu_ptr (pmu->pmu_cpu_context);struct remote_output ro = { .rb = event->rb, };
Patches currently in stable-queue which might be from [email protected] are
queue-4.7/perf-core-use-this_cpu_ptr-when-stopping-aux-events.patch queue-4.7/drivers-perf-arm_pmu-fix-leak-in-error-path.patch