Commit c171b552a7d316c7e1c3ad6f70a30178dd53e14c

Authored by Li Zefan
Committed by Ingo Molnar
1 parent 6fb2915df7

perf trace: Add filter Suppport

Add a new option "--filter <filter_str>" to perf record, and
it should be right after "-e trace_point":

 #./perf record -R -f -e irq:irq_handler_entry --filter irq==18
 ^C
 # ./perf trace
            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

See Documentation/trace/events.txt for the syntax of filter
expressions.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <4AD6955F.90602@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 3 changed files with 40 additions and 3 deletions Side-by-side Diff

tools/perf/builtin-record.c
... ... @@ -374,9 +374,11 @@
374 374  
375 375 static void create_counter(int counter, int cpu, pid_t pid)
376 376 {
  377 + char *filter = filters[counter];
377 378 struct perf_event_attr *attr = attrs + counter;
378 379 struct perf_header_attr *h_attr;
379 380 int track = !counter; /* only the first counter needs these */
  381 + int ret;
380 382 struct {
381 383 u64 count;
382 384 u64 time_enabled;
... ... @@ -479,7 +481,6 @@
479 481 multiplex_fd = fd[nr_cpu][counter];
480 482  
481 483 if (multiplex && fd[nr_cpu][counter] != multiplex_fd) {
482   - int ret;
483 484  
484 485 ret = ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
485 486 assert(ret != -1);
... ... @@ -499,6 +500,16 @@
499 500 }
500 501 }
501 502  
  503 + if (filter != NULL) {
  504 + ret = ioctl(fd[nr_cpu][counter],
  505 + PERF_EVENT_IOC_SET_FILTER, filter);
  506 + if (ret) {
  507 + error("failed to set filter with %d (%s)\n", errno,
  508 + strerror(errno));
  509 + exit(-1);
  510 + }
  511 + }
  512 +
502 513 ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE);
503 514 }
504 515  
... ... @@ -676,6 +687,8 @@
676 687 OPT_CALLBACK('e', "event", NULL, "event",
677 688 "event selector. use 'perf list' to list available events",
678 689 parse_events),
  690 + OPT_CALLBACK(0, "filter", NULL, "filter",
  691 + "event filter", parse_filter),
679 692 OPT_INTEGER('p', "pid", &target_pid,
680 693 "record events on existing pid"),
681 694 OPT_INTEGER('r', "realtime", &realtime_prio,
tools/perf/util/parse-events.c
... ... @@ -8,9 +8,10 @@
8 8 #include "cache.h"
9 9 #include "header.h"
10 10  
11   -int nr_counters;
  11 +int nr_counters;
12 12  
13 13 struct perf_event_attr attrs[MAX_COUNTERS];
  14 +char *filters[MAX_COUNTERS];
14 15  
15 16 struct event_symbol {
16 17 u8 type;
... ... @@ -708,7 +709,6 @@
708 709 perf_header__push_event(id, orgname);
709 710 }
710 711  
711   -
712 712 int parse_events(const struct option *opt __used, const char *str, int unset __used)
713 713 {
714 714 struct perf_event_attr attr;
... ... @@ -741,6 +741,28 @@
741 741 while (isspace(*str))
742 742 ++str;
743 743 }
  744 +
  745 + return 0;
  746 +}
  747 +
  748 +int parse_filter(const struct option *opt __used, const char *str,
  749 + int unset __used)
  750 +{
  751 + int i = nr_counters - 1;
  752 + int len = strlen(str);
  753 +
  754 + if (i < 0 || attrs[i].type != PERF_TYPE_TRACEPOINT) {
  755 + fprintf(stderr,
  756 + "-F option should follow a -e tracepoint option\n");
  757 + return -1;
  758 + }
  759 +
  760 + filters[i] = malloc(len + 1);
  761 + if (!filters[i]) {
  762 + fprintf(stderr, "not enough memory to hold filter string\n");
  763 + return -1;
  764 + }
  765 + strcpy(filters[i], str);
744 766  
745 767 return 0;
746 768 }
tools/perf/util/parse-events.h
... ... @@ -17,11 +17,13 @@
17 17 extern int nr_counters;
18 18  
19 19 extern struct perf_event_attr attrs[MAX_COUNTERS];
  20 +extern char *filters[MAX_COUNTERS];
20 21  
21 22 extern const char *event_name(int ctr);
22 23 extern const char *__event_name(int type, u64 config);
23 24  
24 25 extern int parse_events(const struct option *opt, const char *str, int unset);
  26 +extern int parse_filter(const struct option *opt, const char *str, int unset);
25 27  
26 28 #define EVENTS_HELP_MAX (128*1024)
27 29