perf trace: Support ! in -e expressions
authorArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 21 Aug 2013 15:56:21 +0000 (12:56 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 26 Aug 2013 20:25:41 +0000 (17:25 -0300)
So that we can ask for all but a set of syscalls to be traced.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-9j6hvap23qanyl96wx4mrj9k@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/Documentation/perf-trace.txt
tools/perf/builtin-trace.c

index cb3371eb597db65b4d677a6adf9298d4df0ee159..4754f11a862b2d51c7dd6a03cd8c03391aaf975c 100644 (file)
@@ -30,6 +30,8 @@ OPTIONS
 -e::
 --expr::
        List of events to show, currently only syscall names.
+       Prefixing with ! shows all syscalls but the ones specified.  You may
+       need to escape it.
 
 -o::
 --output=::
index 9891d8cdb73dd5ff5710410f75ae39f717f1fb15..6ab7a7a5e66e14526fe92697e7de30cdcc5c3852 100644 (file)
@@ -114,8 +114,9 @@ struct trace {
        struct machine          host;
        u64                     base_time;
        FILE                    *output;
-       struct strlist          *ev_qualifier;
        unsigned long           nr_events;
+       struct strlist          *ev_qualifier;
+       bool                    not_ev_qualifier;
        bool                    sched;
        bool                    multiple_threads;
        double                  duration_filter;
@@ -234,13 +235,17 @@ static int trace__read_syscall_info(struct trace *trace, int id)
        sc = trace->syscalls.table + id;
        sc->name = name;
 
-       if (trace->ev_qualifier && !strlist__find(trace->ev_qualifier, name)) {
-               sc->filtered = true;
-               /*
-                * No need to do read tracepoint information since this will be
-                * filtered out.
-                */
-               return 0;
+       if (trace->ev_qualifier) {
+               bool in = strlist__find(trace->ev_qualifier, name) != NULL;
+
+               if (!(in ^ trace->not_ev_qualifier)) {
+                       sc->filtered = true;
+                       /*
+                        * No need to do read tracepoint information since this will be
+                        * filtered out.
+                        */
+                       return 0;
+               }
        }
 
        sc->fmt  = syscall_fmt__find(sc->name);
@@ -725,7 +730,12 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
        }
 
        if (ev_qualifier_str != NULL) {
-               trace.ev_qualifier = strlist__new(true, ev_qualifier_str);
+               const char *s = ev_qualifier_str;
+
+               trace.not_ev_qualifier = *s == '!';
+               if (trace.not_ev_qualifier)
+                       ++s;
+               trace.ev_qualifier = strlist__new(true, s);
                if (trace.ev_qualifier == NULL) {
                        fputs("Not enough memory to parse event qualifier",
                              trace.output);