lkml.org 
[lkml]   [2010]   [Jun]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/5] perf: Provide a proper stop action for software events
    Date
    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@gmail.com>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
    Cc: Paul Mackerras <paulus@samba.org>
    Cc: Stephane Eranian <eranian@google.com>
    Cc: Cyrill Gorcunov <gorcunov@gmail.com>
    Cc: Zhang Yanmin <yanmin_zhang@linux.intel.com>
    Cc: Steven Rostedt <rostedt@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


    \
     
     \ /
      Last update: 2010-06-12 09:37    [W:3.639 / U:0.120 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site