Prev: tmpfs: Quick token library to allow scalable retrieval of tokens from token jar
Next: [PATCH 0/5 v3] perf events finer grained context instrumentation / context exclusion
From: Frederic Weisbecker on 12 Jun 2010 03:40 In order to introduce new context exclusions, software events will have to eventually stop when needed. We'll want perf_event_stop() to act on every events. To achieve this, remove the stub stop/start pmu callbacks of software and tracepoint events that fixed a race in perf_adjust_period, and do an explicit check to only reset the hardware event using the start/stop callbacks. Signed-off-by: Frederic Weisbecker <fweisbec(a)gmail.com> Cc: Ingo Molnar <mingo(a)elte.hu> Cc: Peter Zijlstra <a.p.zijlstra(a)chello.nl> Cc: Arnaldo Carvalho de Melo <acme(a)redhat.com> Cc: Paul Mackerras <paulus(a)samba.org> Cc: Stephane Eranian <eranian(a)google.com> Cc: Cyrill Gorcunov <gorcunov(a)gmail.com> Cc: Zhang Yanmin <yanmin_zhang(a)linux.intel.com> Cc: Steven Rostedt <rostedt(a)goodmis.org> --- kernel/perf_event.c | 30 +++++++++++++++++------------- 1 files changed, 17 insertions(+), 13 deletions(-) diff --git a/kernel/perf_event.c b/kernel/perf_event.c index c772a3d..95a56ed 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -1541,11 +1541,24 @@ static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count) hwc->sample_period = sample_period; if (local64_read(&hwc->period_left) > 8*sample_period) { - perf_disable(); - perf_event_stop(event); + bool software_event = is_software_event(event); + + /* + * Only hardware events need their irq period to be + * reprogrammed. And stopping and restarting software + * events here would be dangerously racy. + */ + if (!software_event) { + perf_disable(); + perf_event_stop(event); + } + local64_set(&hwc->period_left, 0); - perf_event_start(event); - perf_enable(); + + if (!software_event) { + perf_event_start(event); + perf_enable(); + } } } @@ -4286,16 +4299,9 @@ static void perf_swevent_void(struct perf_event *event) { } -static int perf_swevent_int(struct perf_event *event) -{ - return 0; -} - static const struct pmu perf_ops_generic = { .enable = perf_swevent_enable, .disable = perf_swevent_disable, - .start = perf_swevent_int, - .stop = perf_swevent_void, .read = perf_swevent_read, .unthrottle = perf_swevent_void, /* hwc->interrupts already reset */ }; @@ -4578,8 +4584,6 @@ static int swevent_hlist_get(struct perf_event *event) static const struct pmu perf_ops_tracepoint = { .enable = perf_trace_enable, .disable = perf_trace_disable, - .start = perf_swevent_int, - .stop = perf_swevent_void, .read = perf_swevent_read, .unthrottle = perf_swevent_void, }; -- 1.6.2.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ |