aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/Documentation/perf-probe.txt14
-rw-r--r--tools/perf/builtin-probe.c34
-rw-r--r--tools/perf/util/probe-event.c66
-rw-r--r--tools/perf/util/probe-event.h3
4 files changed, 90 insertions, 27 deletions
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index fcc51fe0195c..32fb18f1695d 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -77,6 +77,12 @@ OPTIONS
77--funcs:: 77--funcs::
78 Show available functions in given module or kernel. 78 Show available functions in given module or kernel.
79 79
80--filter=FILTER::
81 (Only for --vars) Set filter for variables. FILTER is a combination of
82 glob pattern, see FILTER PATTERN for details.
83 Default FILTER is "!__k???tab_* & !__crc_*".
84 If several filters are specified, only the last filter is valid.
85
80-f:: 86-f::
81--force:: 87--force::
82 Forcibly add events with existing name. 88 Forcibly add events with existing name.
@@ -139,6 +145,14 @@ e.g.
139 145
140This provides some sort of flexibility and robustness to probe point definitions against minor code changes. For example, actual 10th line of schedule() can be moved easily by modifying schedule(), but the same line matching 'rq=cpu_rq*' may still exist in the function.) 146This provides some sort of flexibility and robustness to probe point definitions against minor code changes. For example, actual 10th line of schedule() can be moved easily by modifying schedule(), but the same line matching 'rq=cpu_rq*' may still exist in the function.)
141 147
148FILTER PATTERN
149--------------
150 The filter pattern is a glob matching pattern(s) to filter variables.
151 In addition, you can use "!" for specifying filter-out rule. You also can give several rules combined with "&" or "|", and fold those rules as one rule by using "(" ")".
152
153e.g.
154 With --filter "foo* | bar*", perf probe -V shows variables which start with "foo" or "bar".
155 With --filter "!foo* & *bar", perf probe -V shows variables which don't start with "foo" and end with "bar", like "fizzbar". But "foobar" is filtered out.
142 156
143EXAMPLES 157EXAMPLES
144-------- 158--------
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 6cf708aba7c9..abb423e164c8 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -36,6 +36,7 @@
36#include "builtin.h" 36#include "builtin.h"
37#include "util/util.h" 37#include "util/util.h"
38#include "util/strlist.h" 38#include "util/strlist.h"
39#include "util/strfilter.h"
39#include "util/symbol.h" 40#include "util/symbol.h"
40#include "util/debug.h" 41#include "util/debug.h"
41#include "util/debugfs.h" 42#include "util/debugfs.h"
@@ -43,6 +44,7 @@
43#include "util/probe-finder.h" 44#include "util/probe-finder.h"
44#include "util/probe-event.h" 45#include "util/probe-event.h"
45 46
47#define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*"
46#define MAX_PATH_LEN 256 48#define MAX_PATH_LEN 256
47 49
48/* Session management structure */ 50/* Session management structure */
@@ -60,6 +62,7 @@ static struct {
60 struct line_range line_range; 62 struct line_range line_range;
61 const char *target_module; 63 const char *target_module;
62 int max_probe_points; 64 int max_probe_points;
65 struct strfilter *filter;
63} params; 66} params;
64 67
65/* Parse an event definition. Note that any error must die. */ 68/* Parse an event definition. Note that any error must die. */
@@ -156,6 +159,27 @@ static int opt_show_vars(const struct option *opt __used,
156 159
157 return ret; 160 return ret;
158} 161}
162
163static int opt_set_filter(const struct option *opt __used,
164 const char *str, int unset __used)
165{
166 const char *err;
167
168 if (str) {
169 pr_debug2("Set filter: %s\n", str);
170 if (params.filter)
171 strfilter__delete(params.filter);
172 params.filter = strfilter__new(str, &err);
173 if (!params.filter) {
174 pr_err("Filter parse error at %ld.\n", err - str + 1);
175 pr_err("Source: \"%s\"\n", str);
176 pr_err(" %*c\n", (int)(err - str + 1), '^');
177 return -EINVAL;
178 }
179 }
180
181 return 0;
182}
159#endif 183#endif
160 184
161static const char * const probe_usage[] = { 185static const char * const probe_usage[] = {
@@ -212,6 +236,10 @@ static const struct option options[] = {
212 "Show accessible variables on PROBEDEF", opt_show_vars), 236 "Show accessible variables on PROBEDEF", opt_show_vars),
213 OPT_BOOLEAN('\0', "externs", &params.show_ext_vars, 237 OPT_BOOLEAN('\0', "externs", &params.show_ext_vars,
214 "Show external variables too (with --vars only)"), 238 "Show external variables too (with --vars only)"),
239 OPT_CALLBACK('\0', "filter", NULL,
240 "[!]FILTER", "Set a variable filter (with --vars only)\n"
241 "\t\t\t(default: \"" DEFAULT_VAR_FILTER "\")",
242 opt_set_filter),
215 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 243 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
216 "file", "vmlinux pathname"), 244 "file", "vmlinux pathname"),
217 OPT_STRING('s', "source", &symbol_conf.source_prefix, 245 OPT_STRING('s', "source", &symbol_conf.source_prefix,
@@ -324,10 +352,16 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
324 " --add/--del.\n"); 352 " --add/--del.\n");
325 usage_with_options(probe_usage, options); 353 usage_with_options(probe_usage, options);
326 } 354 }
355 if (!params.filter)
356 params.filter = strfilter__new(DEFAULT_VAR_FILTER,
357 NULL);
358
327 ret = show_available_vars(params.events, params.nevents, 359 ret = show_available_vars(params.events, params.nevents,
328 params.max_probe_points, 360 params.max_probe_points,
329 params.target_module, 361 params.target_module,
362 params.filter,
330 params.show_ext_vars); 363 params.show_ext_vars);
364 strfilter__delete(params.filter);
331 if (ret < 0) 365 if (ret < 0)
332 pr_err(" Error: Failed to show vars. (%d)\n", ret); 366 pr_err(" Error: Failed to show vars. (%d)\n", ret);
333 return ret; 367 return ret;
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 859d377a3df3..077e0518f0f7 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -451,12 +451,14 @@ end:
451} 451}
452 452
453static int show_available_vars_at(int fd, struct perf_probe_event *pev, 453static int show_available_vars_at(int fd, struct perf_probe_event *pev,
454 int max_vls, bool externs) 454 int max_vls, struct strfilter *_filter,
455 bool externs)
455{ 456{
456 char *buf; 457 char *buf;
457 int ret, i; 458 int ret, i, nvars;
458 struct str_node *node; 459 struct str_node *node;
459 struct variable_list *vls = NULL, *vl; 460 struct variable_list *vls = NULL, *vl;
461 const char *var;
460 462
461 buf = synthesize_perf_probe_point(&pev->point); 463 buf = synthesize_perf_probe_point(&pev->point);
462 if (!buf) 464 if (!buf)
@@ -464,36 +466,45 @@ static int show_available_vars_at(int fd, struct perf_probe_event *pev,
464 pr_debug("Searching variables at %s\n", buf); 466 pr_debug("Searching variables at %s\n", buf);
465 467
466 ret = find_available_vars_at(fd, pev, &vls, max_vls, externs); 468 ret = find_available_vars_at(fd, pev, &vls, max_vls, externs);
467 if (ret > 0) { 469 if (ret <= 0) {
468 /* Some variables were found */ 470 pr_err("Failed to find variables at %s (%d)\n", buf, ret);
469 fprintf(stdout, "Available variables at %s\n", buf); 471 goto end;
470 for (i = 0; i < ret; i++) { 472 }
471 vl = &vls[i]; 473 /* Some variables are found */
472 /* 474 fprintf(stdout, "Available variables at %s\n", buf);
473 * A probe point might be converted to 475 for (i = 0; i < ret; i++) {
474 * several trace points. 476 vl = &vls[i];
475 */ 477 /*
476 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, 478 * A probe point might be converted to
477 vl->point.offset); 479 * several trace points.
478 free(vl->point.symbol); 480 */
479 if (vl->vars) { 481 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol,
480 strlist__for_each(node, vl->vars) 482 vl->point.offset);
483 free(vl->point.symbol);
484 nvars = 0;
485 if (vl->vars) {
486 strlist__for_each(node, vl->vars) {
487 var = strchr(node->s, '\t') + 1;
488 if (strfilter__compare(_filter, var)) {
481 fprintf(stdout, "\t\t%s\n", node->s); 489 fprintf(stdout, "\t\t%s\n", node->s);
482 strlist__delete(vl->vars); 490 nvars++;
483 } else 491 }
484 fprintf(stdout, "(No variables)\n"); 492 }
493 strlist__delete(vl->vars);
485 } 494 }
486 free(vls); 495 if (nvars == 0)
487 } else 496 fprintf(stdout, "\t\t(No matched variables)\n");
488 pr_err("Failed to find variables at %s (%d)\n", buf, ret); 497 }
489 498 free(vls);
499end:
490 free(buf); 500 free(buf);
491 return ret; 501 return ret;
492} 502}
493 503
494/* Show available variables on given probe point */ 504/* Show available variables on given probe point */
495int show_available_vars(struct perf_probe_event *pevs, int npevs, 505int show_available_vars(struct perf_probe_event *pevs, int npevs,
496 int max_vls, const char *module, bool externs) 506 int max_vls, const char *module,
507 struct strfilter *_filter, bool externs)
497{ 508{
498 int i, fd, ret = 0; 509 int i, fd, ret = 0;
499 510
@@ -510,7 +521,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
510 setup_pager(); 521 setup_pager();
511 522
512 for (i = 0; i < npevs && ret >= 0; i++) 523 for (i = 0; i < npevs && ret >= 0; i++)
513 ret = show_available_vars_at(fd, &pevs[i], max_vls, externs); 524 ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter,
525 externs);
514 526
515 close(fd); 527 close(fd);
516 return ret; 528 return ret;
@@ -556,7 +568,9 @@ int show_line_range(struct line_range *lr __unused, const char *module __unused)
556 568
557int show_available_vars(struct perf_probe_event *pevs __unused, 569int show_available_vars(struct perf_probe_event *pevs __unused,
558 int npevs __unused, int max_vls __unused, 570 int npevs __unused, int max_vls __unused,
559 const char *module __unused, bool externs __unused) 571 const char *module __unused,
572 struct strfilter *filter __unused,
573 bool externs __unused)
560{ 574{
561 pr_warning("Debuginfo-analysis is not supported.\n"); 575 pr_warning("Debuginfo-analysis is not supported.\n");
562 return -ENOSYS; 576 return -ENOSYS;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 1fb4f18337d3..4e80b2bbc516 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -3,6 +3,7 @@
3 3
4#include <stdbool.h> 4#include <stdbool.h>
5#include "strlist.h" 5#include "strlist.h"
6#include "strfilter.h"
6 7
7extern bool probe_event_dry_run; 8extern bool probe_event_dry_run;
8 9
@@ -126,7 +127,7 @@ extern int show_perf_probe_events(void);
126extern int show_line_range(struct line_range *lr, const char *module); 127extern int show_line_range(struct line_range *lr, const char *module);
127extern int show_available_vars(struct perf_probe_event *pevs, int npevs, 128extern int show_available_vars(struct perf_probe_event *pevs, int npevs,
128 int max_probe_points, const char *module, 129 int max_probe_points, const char *module,
129 bool externs); 130 struct strfilter *filter, bool externs);
130extern int show_available_funcs(const char *module); 131extern int show_available_funcs(const char *module);
131 132
132 133