lkml.org 
[lkml]   [2015]   [Jun]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH v10 30/50] perf record: Compile scriptlets if pass '.c' to --event
    Date
    This patch enables passing source files to --event directly using:

    # perf record --event bpf-file.c command

    This patch does following works:
    1) Allow passing '.c' file to '--event'. parse_events_load_bpf() is
    expanded to allow caller tell it whether the passed file is source
    file or object.

    2) llvm__compile_bpf() is called to compile the '.c' file, the result
    is saved into memory. Use bpf_object__open_buffer() to load the
    in-memory object.

    Signed-off-by: Wang Nan <wangnan0@huawei.com>
    ---
    tools/perf/util/bpf-loader.c | 17 +++++++++++++++--
    tools/perf/util/bpf-loader.h | 5 +++--
    tools/perf/util/parse-events.c | 4 ++--
    tools/perf/util/parse-events.h | 2 +-
    tools/perf/util/parse-events.l | 3 +++
    tools/perf/util/parse-events.y | 15 +++++++++++++--
    6 files changed, 37 insertions(+), 9 deletions(-)

    diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
    index 07673fc..6a3ec3a 100644
    --- a/tools/perf/util/bpf-loader.c
    +++ b/tools/perf/util/bpf-loader.c
    @@ -9,6 +9,7 @@
    #include "perf.h"
    #include "debug.h"
    #include "bpf-loader.h"
    +#include "llvm-utils.h"

    #define DEFINE_PRINT_FN(name, level) \
    static int libbpf_##name(const char *fmt, ...) \
    @@ -28,7 +29,7 @@ DEFINE_PRINT_FN(debug, 1)

    static bool libbpf_initialized;

    -int bpf__prepare_load(const char *filename)
    +int bpf__prepare_load(const char *filename, bool source)
    {
    struct bpf_object *obj;

    @@ -37,7 +38,19 @@ int bpf__prepare_load(const char *filename)
    libbpf_info,
    libbpf_debug);

    - obj = bpf_object__open(filename);
    + if (source) {
    + void *obj_buf;
    + size_t obj_buf_sz;
    + int err;
    +
    + err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz);
    + if (err)
    + return err;
    + obj = bpf_object__open_buffer(obj_buf, obj_buf_sz);
    + free(obj_buf);
    + } else
    + obj = bpf_object__open(filename);
    +
    if (!obj) {
    pr_err("bpf: failed to load %s\n", filename);
    return -EINVAL;
    diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
    index 39d8d1a..5566be0 100644
    --- a/tools/perf/util/bpf-loader.h
    +++ b/tools/perf/util/bpf-loader.h
    @@ -9,11 +9,12 @@
    #include "debug.h"

    #ifdef HAVE_LIBBPF_SUPPORT
    -int bpf__prepare_load(const char *filename);
    +int bpf__prepare_load(const char *filename, bool source);

    void bpf__clear(void);
    #else
    -static inline int bpf__prepare_load(const char *filename __maybe_unused)
    +static inline int bpf__prepare_load(const char *filename __maybe_unused,
    + bool source __maybe_unused)
    {
    pr_err("ERROR: eBPF object loading is disabled during compiling.\n");
    return -1;
    diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
    index 6f7a7b1..aaee24c 100644
    --- a/tools/perf/util/parse-events.c
    +++ b/tools/perf/util/parse-events.c
    @@ -475,7 +475,7 @@ int parse_events_add_tracepoint(struct list_head *list, int *idx,

    int parse_events_load_bpf(struct list_head *list __maybe_unused,
    int *idx __maybe_unused,
    - char *bpf_file_name)
    + char *bpf_file_name, bool source)
    {
    /*
    * Currently don't link any event to list. BPF object files
    @@ -485,7 +485,7 @@ int parse_events_load_bpf(struct list_head *list __maybe_unused,
    * problem. After that probe events file by file is possible.
    * However, probing cost is still need to be considered.
    */
    - return bpf__prepare_load(bpf_file_name);
    + return bpf__prepare_load(bpf_file_name, source);
    }

    static int
    diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
    index 41b962a..5841d4f 100644
    --- a/tools/perf/util/parse-events.h
    +++ b/tools/perf/util/parse-events.h
    @@ -115,7 +115,7 @@ int parse_events_name(struct list_head *list, char *name);
    int parse_events_add_tracepoint(struct list_head *list, int *idx,
    char *sys, char *event);
    int parse_events_load_bpf(struct list_head *list, int *idx,
    - char *bpf_file_name);
    + char *bpf_file_name, bool source);
    int parse_events_add_numeric(struct parse_events_evlist *data,
    struct list_head *list,
    u32 type, u64 config,
    diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
    index 8328b28..556fa21 100644
    --- a/tools/perf/util/parse-events.l
    +++ b/tools/perf/util/parse-events.l
    @@ -116,6 +116,7 @@ group [^,{}/]*[{][^}]*[}][^,{}/]*
    event_pmu [^,{}/]+[/][^/]*[/][^,{}/]*
    event [^,{}/]+
    bpf_object .*\.(o|bpf)
    +bpf_source .*\.c

    num_dec [0-9]+
    num_hex 0x[a-fA-F0-9]+
    @@ -161,6 +162,7 @@ modifier_bp [rwx]{1,3}

    {event_pmu} |
    {bpf_object} |
    +{bpf_source} |
    {event} {
    BEGIN(INITIAL);
    REWIND(1);
    @@ -264,6 +266,7 @@ r{num_raw_hex} { return raw(yyscanner); }
    {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); }
    {name} { return pmu_str_check(yyscanner); }
    {bpf_object} { return str(yyscanner, PE_BPF_OBJECT); }
    +{bpf_source} { return str(yyscanner, PE_BPF_SOURCE); }
    "/" { BEGIN(config); return '/'; }
    - { return '-'; }
    , { BEGIN(event); return ','; }
    diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
    index 481f3cd..eeb9768 100644
    --- a/tools/perf/util/parse-events.y
    +++ b/tools/perf/util/parse-events.y
    @@ -42,7 +42,7 @@ static inc_group_count(struct list_head *list,
    %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
    %token PE_EVENT_NAME
    %token PE_NAME
    -%token PE_BPF_OBJECT
    +%token PE_BPF_OBJECT PE_BPF_SOURCE
    %token PE_MODIFIER_EVENT PE_MODIFIER_BP
    %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
    %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
    @@ -55,6 +55,7 @@ static inc_group_count(struct list_head *list,
    %type <num> PE_TERM
    %type <str> PE_NAME
    %type <str> PE_BPF_OBJECT
    +%type <str> PE_BPF_SOURCE
    %type <str> PE_NAME_CACHE_TYPE
    %type <str> PE_NAME_CACHE_OP_RESULT
    %type <str> PE_MODIFIER_EVENT
    @@ -431,7 +432,17 @@ PE_BPF_OBJECT
    struct list_head *list;

    ALLOC_LIST(list);
    - ABORT_ON(parse_events_load_bpf(list, &data->idx, $1));
    + ABORT_ON(parse_events_load_bpf(list, &data->idx, $1, false));
    + $$ = list;
    +}
    +|
    +PE_BPF_SOURCE
    +{
    + struct parse_events_evlist *data = _data;
    + struct list_head *list;
    +
    + ALLOC_LIST(list);
    + ABORT_ON(parse_events_load_bpf(list, &data->idx, $1, true));
    $$ = list;
    }

    --
    1.8.3.4


    \
     
     \ /
      Last update: 2015-07-01 04:41    [W:3.803 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site