lkml.org 
[lkml]   [2017]   [Jul]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH] Add "-f" and "-F" flags to watch a "/sys? style file (single number)
    Date
    From: Tony Luck <tony.luck@intel.com>

    -f shows absolute value from the file each time. -F shows the delta
    ---

    This is a proof-of-concept patch to show how "perf" might be extended to
    use the new RDT file system monitoring files. "-f" is useful for the llc_occupancy
    "-F" for the MBM files.

    tools/perf/builtin-c2c.c | 2 ++
    tools/perf/builtin-mem.c | 2 ++
    tools/perf/builtin-record.c | 4 ++++
    tools/perf/builtin-stat.c | 4 ++++
    tools/perf/builtin-top.c | 4 ++++
    tools/perf/builtin-trace.c | 4 ++++
    tools/perf/util/evsel.c | 22 ++++++++++++++++++++++
    tools/perf/util/evsel.h | 1 +
    tools/perf/util/parse-events.c | 17 +++++++++++++++++
    tools/perf/util/parse-events.h | 1 +
    10 files changed, 61 insertions(+)

    diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
    index 475999e48f66..094b84d34f7b 100644
    --- a/tools/perf/builtin-c2c.c
    +++ b/tools/perf/builtin-c2c.c
    @@ -2692,6 +2692,8 @@ static int perf_c2c__record(int argc, const char **argv)
    OPT_CALLBACK('e', "event", &event_set, "event",
    "event selector. Use 'perf mem record -e list' to list available events",
    parse_record_events),
    + OPT_CALLBACK('f', "file", &event_set, "file", "file selector", parse_files_option),
    + OPT_CALLBACK('F', "file", &event_set, "file", "delta file selector", parse_files_option),
    OPT_BOOLEAN('u', "all-user", &all_user, "collect only user level data"),
    OPT_BOOLEAN('k', "all-kernel", &all_kernel, "collect only kernel level data"),
    OPT_UINTEGER('l', "ldlat", &perf_mem_events__loads_ldlat, "setup mem-loads latency"),
    diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
    index e001c0290793..86a332dd30cc 100644
    --- a/tools/perf/builtin-mem.c
    +++ b/tools/perf/builtin-mem.c
    @@ -72,6 +72,8 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
    OPT_CALLBACK('e', "event", &mem, "event",
    "event selector. use 'perf mem record -e list' to list available events",
    parse_record_events),
    + OPT_CALLBACK('f', "file", &mem, "file", "file selector", parse_files_option),
    + OPT_CALLBACK('F', "file", &mem, "file", "delta file selector", parse_files_option),
    OPT_UINTEGER(0, "ldlat", &perf_mem_events__loads_ldlat, "mem-loads latency"),
    OPT_INCR('v', "verbose", &verbose,
    "be more verbose (show counter open errors, etc)"),
    diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
    index 17a14bcce34a..096a7b22f897 100644
    --- a/tools/perf/builtin-record.c
    +++ b/tools/perf/builtin-record.c
    @@ -1551,6 +1551,10 @@ static struct option __record_options[] = {
    OPT_CALLBACK('e', "event", &record.evlist, "event",
    "event selector. use 'perf list' to list available events",
    parse_events_option),
    + OPT_CALLBACK('f', "file", &record.evlist, "file",
    + "file selector", parse_files_option),
    + OPT_CALLBACK('F', "file", &record.evlist, "file",
    + "delta file selector", parse_files_option),
    OPT_CALLBACK(0, "filter", &record.evlist, "filter",
    "event filter", parse_filter),
    OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
    diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
    index 48ac53b199fc..c5da65d0acce 100644
    --- a/tools/perf/builtin-stat.c
    +++ b/tools/perf/builtin-stat.c
    @@ -1736,6 +1736,10 @@ static const struct option stat_options[] = {
    OPT_CALLBACK('e', "event", &evsel_list, "event",
    "event selector. use 'perf list' to list available events",
    parse_events_option),
    + OPT_CALLBACK('f', "file", &evsel_list, "file",
    + "file selector", parse_files_option),
    + OPT_CALLBACK('F', "file", &evsel_list, "file",
    + "delta file selector", parse_files_option),
    OPT_CALLBACK(0, "filter", &evsel_list, "filter",
    "event filter", parse_filter),
    OPT_BOOLEAN('i', "no-inherit", &no_inherit,
    diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
    index 6052376634c0..ded5a9e35c6b 100644
    --- a/tools/perf/builtin-top.c
    +++ b/tools/perf/builtin-top.c
    @@ -1104,6 +1104,10 @@ int cmd_top(int argc, const char **argv)
    OPT_CALLBACK('e', "event", &top.evlist, "event",
    "event selector. use 'perf list' to list available events",
    parse_events_option),
    + OPT_CALLBACK('f', "file", &top.evlist, "file",
    + "file selector", parse_files_option),
    + OPT_CALLBACK('F', "file", &top.evlist, "file",
    + "delta file selector", parse_files_option),
    OPT_U64('c', "count", &opts->user_interval, "event period to sample"),
    OPT_STRING('p', "pid", &target->pid, "pid",
    "profile events on existing process id"),
    diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
    index 4b2a5d298197..b404ebc829bc 100644
    --- a/tools/perf/builtin-trace.c
    +++ b/tools/perf/builtin-trace.c
    @@ -2862,6 +2862,10 @@ int cmd_trace(int argc, const char **argv)
    OPT_CALLBACK('e', "event", &trace, "event",
    "event/syscall selector. use 'perf list' to list available events",
    trace__parse_events_option),
    + OPT_CALLBACK('f', "file", &evsel_list, "file",
    + "file selector", parse_files_option),
    + OPT_CALLBACK('F', "file", &evsel_list, "file",
    + "delta file selector", parse_files_option),
    OPT_BOOLEAN(0, "comm", &trace.show_comm,
    "show the thread COMM next to its id"),
    OPT_BOOLEAN(0, "tool_stats", &trace.show_tool_stats, "show tool stats"),
    diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
    index 413f74df08de..3353571a5c7e 100644
    --- a/tools/perf/util/evsel.c
    +++ b/tools/perf/util/evsel.c
    @@ -1256,6 +1256,21 @@ void perf_counts_values__scale(struct perf_counts_values *count,
    *pscaled = scaled;
    }

    +static int read_sys_file(int fd, struct perf_counts_values *count)
    +{
    + char buf[100];
    + int n;
    + static u64 fake;
    +
    + n = pread(fd, buf, sizeof buf, 0);
    + if (n >= 0) {
    + count->val = n ? strtol(buf, NULL, 0) : 0;
    + count->ena = count->run = ++fake;
    + return 0;
    + } else
    + return -errno;
    +}
    +
    int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
    struct perf_counts_values *count)
    {
    @@ -1264,6 +1279,8 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
    if (FD(evsel, cpu, thread) < 0)
    return -EINVAL;

    + if (evsel->sysfile)
    + return read_sys_file(FD(evsel, cpu, thread), count);
    if (readn(FD(evsel, cpu, thread), count, sizeof(*count)) <= 0)
    return -errno;

    @@ -1556,6 +1573,11 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
    fprintf(stderr, "%.60s\n", graph_dotted_line);
    }

    + if (evsel->sysfile) {
    + FD(evsel, 0, 0) = open(evsel->name, O_RDONLY, 0);
    + return 0;
    + }
    +
    for (cpu = 0; cpu < cpus->nr; cpu++) {

    for (thread = 0; thread < nthreads; thread++) {
    diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
    index d101695c482c..ede30e111947 100644
    --- a/tools/perf/util/evsel.h
    +++ b/tools/perf/util/evsel.h
    @@ -121,6 +121,7 @@ struct perf_evsel {
    bool per_pkg;
    bool precise_max;
    bool ignore_missing_thread;
    + bool sysfile;
    /* parse modifier helper */
    int exclude_GH;
    int nr_members;
    diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
    index 01e779b91c8e..0d725eda476d 100644
    --- a/tools/perf/util/parse-events.c
    +++ b/tools/perf/util/parse-events.c
    @@ -1793,6 +1793,23 @@ int parse_events_option(const struct option *opt, const char *str,
    return ret;
    }

    +int parse_files_option(const struct option *opt, const char *str,
    + int unset __maybe_unused)
    +{
    + struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
    + struct perf_evsel *evsel = calloc(1, sizeof (*evsel));
    +
    + evsel->name = strdup(str);
    + evsel->unit = "";
    + evsel->sysfile = true;
    + evsel->snapshot = (opt->short_name == 'f');
    + evsel->scale = 1.0;
    + INIT_LIST_HEAD(&evsel->config_terms);
    + evsel->bpf_fd = -1;
    + perf_evlist__add(evlist, evsel);
    + return 0;
    +}
    +
    static int
    foreach_evsel_in_last_glob(struct perf_evlist *evlist,
    int (*func)(struct perf_evsel *evsel,
    diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
    index a235f4d6d5e5..7e14a4c66fad 100644
    --- a/tools/perf/util/parse-events.h
    +++ b/tools/perf/util/parse-events.h
    @@ -30,6 +30,7 @@ bool have_tracepoints(struct list_head *evlist);
    const char *event_type(int type);

    int parse_events_option(const struct option *opt, const char *str, int unset);
    +int parse_files_option(const struct option *opt, const char *str, int unset);
    int parse_events(struct perf_evlist *evlist, const char *str,
    struct parse_events_error *error);
    int parse_events_terms(struct list_head *terms, const char *str);
    --
    2.11.0
    \
     
     \ /
      Last update: 2017-07-26 00:44    [W:4.137 / U:0.240 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site