From 3c3441ad4ca1f1c0d3af979b1a97d25925bda5af Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 15 Feb 2011 22:26:07 +0100 Subject: [PATCH] --- yaml --- r: 233551 b: refs/heads/master c: 4fe757dd48a9e95e1a071291f15dda5421dacb66 h: refs/heads/master i: 233549: 95ed869b04719e272d6bd5be71f16f91677da152 233547: 0e44b8b551f74b10d2d5f59f942a92c47fb8cc96 233543: 25c92c1a6563f8f141d9436610a378a9b79d0b13 233535: 678e63f57ca284d886eb4a2fc9e3bc7625f4e448 v: v3 --- [refs] | 2 +- trunk/kernel/perf_event.c | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index eaaa816501b6..ae96d2da466e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7d44ec193d95416d1342cdd86392a1eeb7461186 +refs/heads/master: 4fe757dd48a9e95e1a071291f15dda5421dacb66 diff --git a/trunk/kernel/perf_event.c b/trunk/kernel/perf_event.c index 999835b6112b..656222fcf767 100644 --- a/trunk/kernel/perf_event.c +++ b/trunk/kernel/perf_event.c @@ -782,6 +782,10 @@ void perf_event_disable(struct perf_event *event) raw_spin_unlock_irq(&ctx->lock); } +#define MAX_INTERRUPTS (~0ULL) + +static void perf_log_throttle(struct perf_event *event, int enable); + static int event_sched_in(struct perf_event *event, struct perf_cpu_context *cpuctx, @@ -794,6 +798,17 @@ event_sched_in(struct perf_event *event, event->state = PERF_EVENT_STATE_ACTIVE; event->oncpu = smp_processor_id(); + + /* + * Unthrottle events, since we scheduled we might have missed several + * ticks already, also for a heavily scheduling task there is little + * guarantee it'll get a tick in a timely manner. + */ + if (unlikely(event->hw.interrupts == MAX_INTERRUPTS)) { + perf_log_throttle(event, 1); + event->hw.interrupts = 0; + } + /* * The new state must be visible before we turn it on in the hardware: */ @@ -1596,10 +1611,6 @@ void __perf_event_task_sched_in(struct task_struct *task) } } -#define MAX_INTERRUPTS (~0ULL) - -static void perf_log_throttle(struct perf_event *event, int enable); - static u64 perf_calculate_period(struct perf_event *event, u64 nsec, u64 count) { u64 frequency = event->attr.sample_freq;