Messages in this thread Patch in this message | ![/](/images/icornerl.gif) | | Date | Mon, 07 Sep 2009 16:14:30 +0800 | From | Li Zefan <> | Subject | [PATCH 6/6] perf trace: Add filter support |
| |
#./perf record -f -e irq:irq_handler_entry:irq==18:record or #./perf record -f -e irq:irq_handler_entry:irq==18 -R ^C # ./perf trace version = 0.5 perf-4303 ... irq_handler_entry: irq=18 handler=eth0 init-0 ... irq_handler_entry: irq=18 handler=eth0 init-0 ... irq_handler_entry: irq=18 handler=eth0 init-0 ... irq_handler_entry: irq=18 handler=eth0 init-0 ... irq_handler_entry: irq=18 handler=eth0
The usage is not changed if filter is not used:
#./perf record -f -e irq:irq_handler_entry:record
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> --- tools/perf/builtin-record.c | 12 ++++++++++ tools/perf/util/parse-events.c | 46 +++++++++++++++++++++++++++++++++------ tools/perf/util/parse-events.h | 1 + 3 files changed, 52 insertions(+), 7 deletions(-)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 99a12fe..7749982 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -369,9 +369,11 @@ static struct perf_header_attr *get_header_attr(struct perf_counter_attr *a, int static void create_counter(int counter, int cpu, pid_t pid) { + char *filter = filters[counter]; struct perf_counter_attr *attr = attrs + counter; struct perf_header_attr *h_attr; int track = !counter; /* only the first counter needs these */ + int ret; struct { u64 count; u64 time_enabled; @@ -485,6 +487,16 @@ try_again: exit(-1); } + if (attr->type == PERF_TYPE_TRACEPOINT && filter != NULL) { + ret = ioctl(fd[nr_cpu][counter], + PERF_COUNTER_IOC_SET_FILTER, filter); + if (ret) { + error("failed to set filter with %d (%s)\n", errno, + strerror(errno)); + exit(-1); + } + } + ioctl(fd[nr_cpu][counter], PERF_COUNTER_IOC_ENABLE); } diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 892d931..a7d2ef6 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -10,6 +10,7 @@ int nr_counters; struct perf_counter_attr attrs[MAX_COUNTERS]; +char *filters[MAX_COUNTERS]; struct event_symbol { u8 type; @@ -405,15 +406,26 @@ parse_generic_hw_event(const char **str, struct perf_counter_attr *attr) return 1; } +static int tracepoint_event_set_flags(const char *flags, + struct perf_counter_attr *attr) +{ + if (!strncmp(flags, "record", strlen(flags))) { + attr->sample_type |= PERF_SAMPLE_RAW; + return 1; + } + return 0; +} + static int parse_tracepoint_event(const char **strp, struct perf_counter_attr *attr) { + char sys_name[MAX_EVENT_LENGTH]; const char *evt_name; + char *filter; char *flags; - char sys_name[MAX_EVENT_LENGTH]; char id_buf[4]; int fd; - unsigned int sys_length, evt_length; + unsigned int sys_length, evt_length, filter_length; u64 id; char evt_path[MAXPATHLEN]; @@ -433,13 +445,33 @@ static int parse_tracepoint_event(const char **strp, evt_name = evt_name + 1; flags = strchr(evt_name, ':'); - if (flags) { - *flags = '\0'; - flags++; - if (!strncmp(flags, "record", strlen(flags))) - attr->sample_type |= PERF_SAMPLE_RAW; + if (!flags) + goto next; + + *flags++ = '\0'; + if (tracepoint_event_set_flags(flags, attr)) + goto next; + + filter = flags; + + flags = strchr(filter, ':'); + if (!flags) + filter_length = strlen(filter); + else { + filter_length = flags++ - filter; + if (!tracepoint_event_set_flags(flags, attr)) + return 0; + } + + filters[nr_counters] = malloc(filter_length + 1); + if (!filters[nr_counters]) { + fprintf(stderr, "Not enough memory to hold filter string\n"); + exit(-1); } + strncpy(filters[nr_counters], filter, filter_length); + filters[nr_counters][filter_length] = '\0'; +next: evt_length = strlen(evt_name); if (evt_length >= MAX_EVENT_LENGTH) return 0; diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 60704c1..0ae146e 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -17,6 +17,7 @@ extern struct tracepoint_path *tracepoint_id_to_path(u64 config); extern int nr_counters; extern struct perf_counter_attr attrs[MAX_COUNTERS]; +extern char *filters[MAX_COUNTERS]; extern const char *event_name(int ctr); extern const char *__event_name(int type, u64 config); -- 1.6.3
| ![\](/images/icornerr.gif) |