From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Vince Weaver <vincent.weaver@maine.edu>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@kernel.org>
Subject: [PATCH 3.14 06/78] perf: Fix race in removing an event
Date: Mon, 9 Jun 2014 15:47:46 -0700 [thread overview]
Message-ID: <20140609224813.563152130@linuxfoundation.org> (raw)
In-Reply-To: <20140609224813.282275135@linuxfoundation.org>
3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <peterz@infradead.org>
commit 46ce0fe97a6be7532ce6126bb26ce89fed81528c upstream.
When removing a (sibling) event we do:
raw_spin_lock_irq(&ctx->lock);
perf_group_detach(event);
raw_spin_unlock_irq(&ctx->lock);
<hole>
perf_remove_from_context(event);
raw_spin_lock_irq(&ctx->lock);
...
raw_spin_unlock_irq(&ctx->lock);
Now, assuming the event is a sibling, it will be 'unreachable' for
things like ctx_sched_out() because that iterates the
groups->siblings, and we just unhooked the sibling.
So, if during <hole> we get ctx_sched_out(), it will miss the event
and not call event_sched_out() on it, leaving it programmed on the
PMU.
The subsequent perf_remove_from_context() call will find the ctx is
inactive and only call list_del_event() to remove the event from all
other lists.
Hereafter we can proceed to free the event; while still programmed!
Close this hole by moving perf_group_detach() inside the same
ctx->lock region(s) perf_remove_from_context() has.
The condition on inherited events only in __perf_event_exit_task() is
likely complete crap because non-inherited events are part of groups
too and we're tearing down just the same. But leave that for another
patch.
Most-likely-Fixes: e03a9a55b4e ("perf: Change close() semantics for group events")
Reported-by: Vince Weaver <vincent.weaver@maine.edu>
Tested-by: Vince Weaver <vincent.weaver@maine.edu>
Much-staring-at-traces-by: Vince Weaver <vincent.weaver@maine.edu>
Much-staring-at-traces-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20140505093124.GN17778@laptop.programming.kicks-ass.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/events/core.c | 47 ++++++++++++++++++++++++++---------------------
1 file changed, 26 insertions(+), 21 deletions(-)
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1439,6 +1439,11 @@ group_sched_out(struct perf_event *group
cpuctx->exclusive = 0;
}
+struct remove_event {
+ struct perf_event *event;
+ bool detach_group;
+};
+
/*
* Cross CPU call to remove a performance event
*
@@ -1447,12 +1452,15 @@ group_sched_out(struct perf_event *group
*/
static int __perf_remove_from_context(void *info)
{
- struct perf_event *event = info;
+ struct remove_event *re = info;
+ struct perf_event *event = re->event;
struct perf_event_context *ctx = event->ctx;
struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
raw_spin_lock(&ctx->lock);
event_sched_out(event, cpuctx, ctx);
+ if (re->detach_group)
+ perf_group_detach(event);
list_del_event(event, ctx);
if (!ctx->nr_events && cpuctx->task_ctx == ctx) {
ctx->is_active = 0;
@@ -1477,10 +1485,14 @@ static int __perf_remove_from_context(vo
* When called from perf_event_exit_task, it's OK because the
* context has been detached from its task.
*/
-static void perf_remove_from_context(struct perf_event *event)
+static void perf_remove_from_context(struct perf_event *event, bool detach_group)
{
struct perf_event_context *ctx = event->ctx;
struct task_struct *task = ctx->task;
+ struct remove_event re = {
+ .event = event,
+ .detach_group = detach_group,
+ };
lockdep_assert_held(&ctx->mutex);
@@ -1489,12 +1501,12 @@ static void perf_remove_from_context(str
* Per cpu events are removed via an smp call and
* the removal is always successful.
*/
- cpu_function_call(event->cpu, __perf_remove_from_context, event);
+ cpu_function_call(event->cpu, __perf_remove_from_context, &re);
return;
}
retry:
- if (!task_function_call(task, __perf_remove_from_context, event))
+ if (!task_function_call(task, __perf_remove_from_context, &re))
return;
raw_spin_lock_irq(&ctx->lock);
@@ -1511,6 +1523,8 @@ retry:
* Since the task isn't running, its safe to remove the event, us
* holding the ctx->lock ensures the task won't get scheduled in.
*/
+ if (detach_group)
+ perf_group_detach(event);
list_del_event(event, ctx);
raw_spin_unlock_irq(&ctx->lock);
}
@@ -3279,10 +3293,7 @@ int perf_event_release_kernel(struct per
* to trigger the AB-BA case.
*/
mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING);
- raw_spin_lock_irq(&ctx->lock);
- perf_group_detach(event);
- raw_spin_unlock_irq(&ctx->lock);
- perf_remove_from_context(event);
+ perf_remove_from_context(event, true);
mutex_unlock(&ctx->mutex);
free_event(event);
@@ -7175,7 +7186,7 @@ SYSCALL_DEFINE5(perf_event_open,
struct perf_event_context *gctx = group_leader->ctx;
mutex_lock(&gctx->mutex);
- perf_remove_from_context(group_leader);
+ perf_remove_from_context(group_leader, false);
/*
* Removing from the context ends up with disabled
@@ -7185,7 +7196,7 @@ SYSCALL_DEFINE5(perf_event_open,
perf_event__state_init(group_leader);
list_for_each_entry(sibling, &group_leader->sibling_list,
group_entry) {
- perf_remove_from_context(sibling);
+ perf_remove_from_context(sibling, false);
perf_event__state_init(sibling);
put_ctx(gctx);
}
@@ -7315,7 +7326,7 @@ void perf_pmu_migrate_context(struct pmu
mutex_lock(&src_ctx->mutex);
list_for_each_entry_safe(event, tmp, &src_ctx->event_list,
event_entry) {
- perf_remove_from_context(event);
+ perf_remove_from_context(event, false);
unaccount_event_cpu(event, src_cpu);
put_ctx(src_ctx);
list_add(&event->migrate_entry, &events);
@@ -7377,13 +7388,7 @@ __perf_event_exit_task(struct perf_event
struct perf_event_context *child_ctx,
struct task_struct *child)
{
- if (child_event->parent) {
- raw_spin_lock_irq(&child_ctx->lock);
- perf_group_detach(child_event);
- raw_spin_unlock_irq(&child_ctx->lock);
- }
-
- perf_remove_from_context(child_event);
+ perf_remove_from_context(child_event, !!child_event->parent);
/*
* It can happen that the parent exits first, and has events
@@ -7868,14 +7873,14 @@ static void perf_pmu_rotate_stop(struct
static void __perf_event_exit_context(void *__info)
{
+ struct remove_event re = { .detach_group = false };
struct perf_event_context *ctx = __info;
- struct perf_event *event;
perf_pmu_rotate_stop(ctx->pmu);
rcu_read_lock();
- list_for_each_entry_rcu(event, &ctx->event_list, event_entry)
- __perf_remove_from_context(event);
+ list_for_each_entry_rcu(re.event, &ctx->event_list, event_entry)
+ __perf_remove_from_context(&re);
rcu_read_unlock();
}
next prev parent reply other threads:[~2014-06-09 23:15 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-09 22:47 [PATCH 3.14 00/78] 3.14.7-stable review Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 01/78] sched: Use CPUPRI_NR_PRIORITIES instead of MAX_RT_PRIO in cpupri check Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 02/78] sched/deadline: Fix memory leak Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 03/78] sched: Sanitize irq accounting madness Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 04/78] perf: Prevent false warning in perf_swevent_add Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 05/78] perf: Limit perf_event_attr::sample_period to 63 bits Greg Kroah-Hartman
2014-06-09 22:47 ` Greg Kroah-Hartman [this message]
2014-06-09 22:47 ` [PATCH 3.14 07/78] mm/memory-failure.c: fix memory leak by race between poison and unpoison Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 08/78] Documentation: fix DOCBOOKS=... building Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 09/78] hwmon: (ntc_thermistor) Fix dependencies Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 10/78] hwmon: (ntc_thermistor) Fix OF device ID mapping Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 11/78] drm/gf119-/disp: fix nasty bug which can clobber SOR0s clock setup Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 16/78] SCSI: scsi_transport_sas: move bsg destructor into sas_rphy_remove Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 18/78] ARM: omap5: hwmod_data: Correct IDLEMODE for McPDM Greg Kroah-Hartman
2014-06-09 22:47 ` [PATCH 3.14 19/78] ARM: OMAP2+: nand: Fix NAND on OMAP2 and OMAP3 boards Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 21/78] ARM: OMAP4: Fix the boot regression with CPU_IDLE enabled Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 22/78] ARM: 8051/1: put_user: fix possible data corruption in put_user Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 24/78] cpufreq: cpu0: drop wrong devm usage Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 25/78] cpufreq: remove race while accessing cur_policy Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 26/78] firewire: revert to 4 GB RDMA, fix protocols using Memory Space Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 27/78] MIPS: Fix typo when reporting cache and ftlb errors for ImgTec cores Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 28/78] dm thin: add no_space_timeout dm-thin-pool module param Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 29/78] dm cache: always split discards on cache block boundaries Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 30/78] Revert "revert "mm: vmscan: do not swap anon pages just because free+file is low"" Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 31/78] virtio_blk: fix race between start and stop queue Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 32/78] sched: Disallow sched_attr::sched_policy < 0 Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 33/78] sched: Make sched_setattr() correctly return -EFBIG Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 34/78] sched/deadline: Change sched_getparam() behaviour vs SCHED_DEADLINE Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 35/78] sched/deadline: Restrict user params max value to 2^63 ns Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 36/78] sched: Fix hotplug vs. set_cpus_allowed_ptr() Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 37/78] sched/dl: Fix race in dl_task_timer() Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 39/78] drm/i915: Only copy back the modified fields to userspace from execbuffer Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 40/78] drm/radeon/dpm: resume fixes for some systems Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 42/78] libata: Blacklist queued trim for Crucial M500 Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 43/78] sched: Fix sched_policy < 0 comparison Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 44/78] md: always set MD_RECOVERY_INTR when aborting a reshape or other "resync" Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 45/78] md: always set MD_RECOVERY_INTR when interrupting a reshape thread Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 47/78] Staging: speakup: Move pasting into a work item Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 48/78] staging: comedi: ni_daq_700: add mux settling delay Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 49/78] Staging: speakup: Update __speakup_paste_selection() tty (ab)usage to match vt Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 50/78] staging: r8192e_pci: fix htons error Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 51/78] Bluetooth: Fix L2CAP LE debugfs entries permissions Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 52/78] ALSA: hda/analog - Fix silent output on ASUS A8JN Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 53/78] ALSA: hda/realtek - Correction of fixup codes for PB V7900 laptop Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 54/78] ALSA: hda/realtek - Fix COEF widget NID for ALC260 replacer fixup Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 55/78] USB: ftdi_sio: add NovaTech OrionLXm product ID Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 58/78] USB: serial: option: add support for Novatel E371 PCIe card Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 59/78] USB: io_ti: fix firmware download on big-endian machines (part 2) Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 60/78] usb: pci-quirks: Prevent Sony VAIO t-series from switching usb ports Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 61/78] USB: Avoid runtime suspend loops for HCDs that cant handle suspend/resume Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 62/78] percpu-refcount: fix usage of this_cpu_ops Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 63/78] intel_pstate: remove unneeded sample buffers Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 64/78] intel_pstate: Remove C0 tracking Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 65/78] intel_pstate: Correct rounding in busy calculation Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 66/78] intel_pstate: add sample time scaling Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 67/78] intel_pstate: Improve initial busy calculation Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 68/78] mm: add !pte_present() check on existing hugetlb_entry callbacks Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 69/78] mm: rmap: fix use-after-free in __put_anon_vma Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 70/78] iser-target: Add missing target_put_sess_cmd for ImmedateData failure Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 71/78] iscsi-target: Fix wrong buffer / buffer overrun in iscsi_change_param_value() Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 72/78] target: Fix alua_access_state attribute OOPs for un-configured devices Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 73/78] netfilter: Fix potential use after free in ip6_route_me_harder() Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 74/78] netfilter: nfnetlink: Fix use after free when it fails to process batch Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 77/78] gpio: mcp23s08: Bug fix of SPI device tree registration Greg Kroah-Hartman
2014-06-09 22:48 ` [PATCH 3.14 78/78] [stable PATCH] iommu/vt-d: Fix missing IOTLB flush in intel_iommu_unmap() Greg Kroah-Hartman
2014-06-10 13:26 ` [PATCH 3.14 00/78] 3.14.7-stable review Satoru Takeuchi
2014-06-10 18:46 ` Greg Kroah-Hartman
2014-06-10 15:11 ` Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140609224813.563152130@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=acme@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=stable@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=vincent.weaver@maine.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox