lkml.org 
[lkml]   [2017]   [Nov]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.2 046/147] perf: Tighten (and fix) the grouping condition
    3.2.95-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Peter Zijlstra <peterz@infradead.org>

    commit c3c87e770458aa004bd7ed3f29945ff436fd6511 upstream.

    The fix from 9fc81d87420d ("perf: Fix events installation during
    moving group") was incomplete in that it failed to recognise that
    creating a group with events for different CPUs is semantically
    broken -- they cannot be co-scheduled.

    Furthermore, it leads to real breakage where, when we create an event
    for CPU Y and then migrate it to form a group on CPU X, the code gets
    confused where the counter is programmed -- triggered in practice
    as well by me via the perf fuzzer.

    Fix this by tightening the rules for creating groups. Only allow
    grouping of counters that can be co-scheduled in the same context.
    This means for the same task and/or the same cpu.

    Fixes: 9fc81d87420d ("perf: Fix events installation during moving group")
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
    Cc: Jiri Olsa <jolsa@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Link: http://lkml.kernel.org/r/20150123125834.090683288@infradead.org
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    include/linux/perf_event.h | 6 ------
    kernel/events/core.c | 15 +++++++++++++--
    2 files changed, 13 insertions(+), 8 deletions(-)

    --- a/include/linux/perf_event.h
    +++ b/include/linux/perf_event.h
    @@ -859,11 +859,6 @@ struct perf_event {
    #endif /* CONFIG_PERF_EVENTS */
    };

    -enum perf_event_context_type {
    - task_context,
    - cpu_context,
    -};
    -
    /**
    * struct perf_event_context - event context structure
    *
    @@ -871,7 +866,6 @@ enum perf_event_context_type {
    */
    struct perf_event_context {
    struct pmu *pmu;
    - enum perf_event_context_type type;
    /*
    * Protect the states of the events in the list,
    * nr_active, and the list:
    --- a/kernel/events/core.c
    +++ b/kernel/events/core.c
    @@ -6116,7 +6116,6 @@ skip_type:
    __perf_event_init_context(&cpuctx->ctx);
    lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex);
    lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock);
    - cpuctx->ctx.type = cpu_context;
    cpuctx->ctx.pmu = pmu;
    cpuctx->jiffies_interval = 1;
    INIT_LIST_HEAD(&cpuctx->rotation_list);
    @@ -6697,7 +6696,19 @@ SYSCALL_DEFINE5(perf_event_open,
    * task or CPU context:
    */
    if (move_group) {
    - if (group_leader->ctx->type != ctx->type)
    + /*
    + * Make sure we're both on the same task, or both
    + * per-cpu events.
    + */
    + if (group_leader->ctx->task != ctx->task)
    + goto err_context;
    +
    + /*
    + * Make sure we're both events for the same CPU;
    + * grouping events for different CPUs is broken; since
    + * you can never concurrently schedule them anyhow.
    + */
    + if (group_leader->cpu != event->cpu)
    goto err_context;
    } else {
    if (group_leader->ctx != ctx)
    \
     
     \ /
      Last update: 2017-11-08 20:57    [W:4.339 / U:0.460 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site