Patch "perf: Fix PERF_EVENT_IOC_PERIOD migration race" has been added to the 3.14-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
perf: Fix PERF_EVENT_IOC_PERIOD migration race
to the 3.14-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-fix-perf_event_ioc_period-migration-race.patch
and it can be found in the queue-3.14 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
c7999c6f3fed9e383d3131474588f282ae6d56b9Mon Sep 17 00:00:00 2001
From: Peter Zijlstra <[email protected]>
Date: Tue, 4 Aug 2015 19:22:49 +0200
Subject: perf: Fix PERF_EVENT_IOC_PERIOD migration race
From: Peter Zijlstra <[email protected]>
commit c7999c6f3fed9e383d3131474588f282ae6d56b9 upstream.
I ran the perf fuzzer, which triggered some WARN()s which are due to trying to stop/restart an event on the wrong CPU.
Use the normal IPI pattern to ensure we run the code on the correct CPU.
--- kernel/events/core.c | 75 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 20 deletions(-)
kernel/events/core.c +55 -20
@@ -3562,28 +3562,21 @@ static void perf_event_for_each(struct pmutex_unlock (&ctx->mutex); } -static int perf_event_period (struct perf_event *event,u64 __user *arg) -{ -struct perf_event_context *ctx = event->ctx; -int ret =0 , active; +struct period_event { +struct perf_event *event;u64 value; +}; -if (!is_sampling_event (event)) -return -EINVAL ; - -if (copy_from_user (&value, arg,sizeof (value))) -return -EFAULT ; - -if (!value) -return -EINVAL ; +static int __perf_event_period (void *info) +{ +struct period_event *pe = info; +struct perf_event *event = pe->event; +struct perf_event_context *ctx = event->ctx; +u64 value = pe->value; +bool active; -raw_spin_lock_irq (&ctx->lock); +raw_spin_lock (&ctx->lock);if (event->attr.freq) { -if (value > sysctl_perf_event_sample_rate) { - ret = -EINVAL ; - goto unlock; - } - event->attr.sample_freq = value; }else { event->attr.sample_period = value;
@@ -3602,11 +3595,53 @@ static int perf_event_period(struct perf event->pmu->start (event,PERF_EF_RELOAD );perf_pmu_enable (ctx->pmu); } +raw_spin_unlock (&ctx->lock); + +return 0 ; +} + +static int perf_event_period (struct perf_event *event,u64 __user *arg) +{ +struct period_event pe = { .event = event, }; +struct perf_event_context *ctx = event->ctx; +struct task_struct *task; +u64 value; + +if (!is_sampling_event (event)) +return -EINVAL ; + +if (copy_from_user (&value, arg,sizeof (value))) +return -EFAULT ; + +if (!value) +return -EINVAL ; + +if (event->attr.freq && value > sysctl_perf_event_sample_rate) +return -EINVAL ; + + task = ctx->task; + pe.value = value; + +if (!task) { +cpu_function_call (event->cpu, __perf_event_period, &pe); +return 0 ; + } + +retry: +if (!task_function_call (task, __perf_event_period, &pe)) +return 0 ; + +raw_spin_lock_irq (&ctx->lock); +if (ctx->is_active) { +raw_spin_unlock_irq (&ctx->lock); + task = ctx->task; + goto retry; + } -unlock: +__perf_event_period (&pe);raw_spin_unlock_irq (&ctx->lock); -return ret; +return 0 ; }static const struct file_operations perf_fops;
Patches currently in stable-queue which might be from [email protected] are
queue-3.14/perf-fix-perf_event_ioc_period-migration-race.patch queue-3.14/ipc-sem.c-update-correct-memory-barriers.patch queue-3.14/perf-fix-fasync-handling-on-inherited-events.patch