lkml.org 
[lkml]   [2013]   [Feb]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 2/7] perf: Introduce hw_perf_event->tp_target and ->tp_list
    sys_perf_event_open()->perf_init_event(event) is called before
    find_get_context(event), this means that event->ctx == NULL when
    class->reg(TRACE_REG_PERF_REGISTER/OPEN) is called and thus it
    can't know if this event is per-task or system-wide.

    This patch adds hw_perf_event->tp_target for PERF_TYPE_TRACEPOINT,
    this is analogous to PERF_TYPE_BREAKPOINT/bp_target we already have.
    The patch also moves ->bp_target up so that it can overlap with the
    new member, this can help the compiler to generate the better code.

    trace_uprobe_register() will use it for prefiltering to avoid the
    unnecessary breakpoints in mm's we do not want to trace.

    ->tp_target doesn't have its own reference, but we can rely on the
    fact that either sys_perf_event_open() holds a reference, or it is
    equal to event->ctx->task. So this pointer is always valid until
    free_event().

    Also add the "struct list_head tp_list" into this union. It is not
    strictly necessary, but it can simplify the next changes and we can
    add it for free.

    Signed-off-by: Oleg Nesterov <oleg@redhat.com>
    ---
    include/linux/perf_event.h | 9 +++++++--
    kernel/events/core.c | 5 ++++-
    2 files changed, 11 insertions(+), 3 deletions(-)

    diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
    index 6bfb2fa..c9775e9 100644
    --- a/include/linux/perf_event.h
    +++ b/include/linux/perf_event.h
    @@ -135,16 +135,21 @@ struct hw_perf_event {
    struct { /* software */
    struct hrtimer hrtimer;
    };
    + struct { /* tracepoint */
    + struct task_struct *tp_target;
    + /* for tp_event->class */
    + struct list_head tp_list;
    + };
    #ifdef CONFIG_HAVE_HW_BREAKPOINT
    struct { /* breakpoint */
    - struct arch_hw_breakpoint info;
    - struct list_head bp_list;
    /*
    * Crufty hack to avoid the chicken and egg
    * problem hw_breakpoint has with context
    * creation and event initalization.
    */
    struct task_struct *bp_target;
    + struct arch_hw_breakpoint info;
    + struct list_head bp_list;
    };
    #endif
    };
    diff --git a/kernel/events/core.c b/kernel/events/core.c
    index 1b2e516..340fb53 100644
    --- a/kernel/events/core.c
    +++ b/kernel/events/core.c
    @@ -6162,11 +6162,14 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,

    if (task) {
    event->attach_state = PERF_ATTACH_TASK;
    +
    + if (attr->type == PERF_TYPE_TRACEPOINT)
    + event->hw.tp_target = task;
    #ifdef CONFIG_HAVE_HW_BREAKPOINT
    /*
    * hw_breakpoint is a bit difficult here..
    */
    - if (attr->type == PERF_TYPE_BREAKPOINT)
    + else if (attr->type == PERF_TYPE_BREAKPOINT)
    event->hw.bp_target = task;
    #endif
    }
    --
    1.5.5.1


    \
     
     \ /
      Last update: 2013-02-04 20:42    [W:6.894 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site