Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751738AbdGYWnG (ORCPT ); Tue, 25 Jul 2017 18:43:06 -0400 Received: from mga07.intel.com ([134.134.136.100]:61787 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751693AbdGYWm7 (ORCPT ); Tue, 25 Jul 2017 18:42:59 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.40,412,1496127600"; d="scan'208";a="291415521" From: "Luck, Tony" To: Thomas Gleixner Cc: vikas.shivappa@linux.intel.com, x86@kernel.org, linux-kernel@vger.kernel.org, hpa@zytor.com, peterz@infradead.org, ravi.v.shankar@intel.com, tony.luck@intel.com, fenghua.yu@intel.com, eranian@google.com, davidcc@google.com, ak@linux.intel.com, reinette.chatre@intel.com Subject: [RFC PATCH] Add "-f" and "-F" flags to watch a "/sys? style file (single number) Date: Tue, 25 Jul 2017 15:42:56 -0700 Message-Id: <20170725224256.13087-1-tony.luck@intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <1501017287-28083-1-git-send-email-vikas.shivappa@linux.intel.com> References: <1501017287-28083-1-git-send-email-vikas.shivappa@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8566 Lines: 208 From: Tony Luck -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