aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2009-12-15 10:32:18 -0500
committerIngo Molnar <mingo@elte.hu>2009-12-15 14:22:03 -0500
commitaf663d75a64d2cc3f18bdb8a29ff4650b9417c16 (patch)
treefbbad1152eb42f561cc8b186b8bb38aabc1e1d94 /tools/perf/util
parentbbbb521bc61008b280c72ad6e29a8a7558d3acfa (diff)
perf probe: Support event name for --add option
Support event name syntax for --add option. This allows users to specify event name for each new event. The --add syntax is: perf probe --add '[EVENT=]SRC:LINE ARGS' or perf probe --add '[EVENT=]FUNC[+OFFS|%return|:RLN][@SRC] ARGS' e.g. ./perf probe --add myprobe1=schedule Note: currently group name is not supported yet, because it can cause name-space confliction with other tracepoint/ hw-breakpoint events. Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Jim Keniston <jkenisto@us.ibm.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: Frank Ch. Eigler <fche@redhat.com> Cc: Jason Baron <jbaron@redhat.com> Cc: K.Prasad <prasad@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Cc: systemtap <systemtap@sources.redhat.com> Cc: DLE <dle-develop@lists.sourceforge.net> Cc: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <20091215153218.17436.84675.stgit@dhcp-100-2-132.bos.redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/probe-event.c74
-rw-r--r--tools/perf/util/probe-event.h3
-rw-r--r--tools/perf/util/probe-finder.h3
3 files changed, 49 insertions, 31 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 5e99e52b0179..3b4cf456165c 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -69,10 +69,23 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
69 char c, nc = 0; 69 char c, nc = 0;
70 /* 70 /*
71 * <Syntax> 71 * <Syntax>
72 * perf probe SRC:LN 72 * perf probe [EVENT=]SRC:LN
73 * perf probe FUNC[+OFFS|%return][@SRC] 73 * perf probe [EVENT=]FUNC[+OFFS|%return][@SRC]
74 *
75 * TODO:Group name support
74 */ 76 */
75 77
78 ptr = strchr(arg, '=');
79 if (ptr) { /* Event name */
80 *ptr = '\0';
81 tmp = ptr + 1;
82 ptr = strchr(arg, ':');
83 if (ptr) /* Group name is not supported yet. */
84 semantic_error("Group name is not supported yet.");
85 pp->event = strdup(arg);
86 arg = tmp;
87 }
88
76 ptr = strpbrk(arg, ":+@%"); 89 ptr = strpbrk(arg, ":+@%");
77 if (ptr) { 90 if (ptr) {
78 nc = *ptr; 91 nc = *ptr;
@@ -188,8 +201,7 @@ void parse_perf_probe_event(const char *str, struct probe_point *pp,
188} 201}
189 202
190/* Parse kprobe_events event into struct probe_point */ 203/* Parse kprobe_events event into struct probe_point */
191void parse_trace_kprobe_event(const char *str, char **group, char **event, 204void parse_trace_kprobe_event(const char *str, struct probe_point *pp)
192 struct probe_point *pp)
193{ 205{
194 char pr; 206 char pr;
195 char *p; 207 char *p;
@@ -205,18 +217,17 @@ void parse_trace_kprobe_event(const char *str, char **group, char **event,
205 217
206 /* Scan event and group name. */ 218 /* Scan event and group name. */
207 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", 219 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
208 &pr, (float *)(void *)group, (float *)(void *)event); 220 &pr, (float *)(void *)&pp->group,
221 (float *)(void *)&pp->event);
209 if (ret != 3) 222 if (ret != 3)
210 semantic_error("Failed to parse event name: %s", argv[0]); 223 semantic_error("Failed to parse event name: %s", argv[0]);
211 pr_debug("Group:%s Event:%s probe:%c\n", *group, *event, pr); 224 pr_debug("Group:%s Event:%s probe:%c\n", pp->group, pp->event, pr);
212
213 if (!pp)
214 goto end;
215 225
216 pp->retprobe = (pr == 'r'); 226 pp->retprobe = (pr == 'r');
217 227
218 /* Scan function name and offset */ 228 /* Scan function name and offset */
219 ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function, &pp->offset); 229 ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function,
230 &pp->offset);
220 if (ret == 1) 231 if (ret == 1)
221 pp->offset = 0; 232 pp->offset = 0;
222 233
@@ -235,7 +246,6 @@ void parse_trace_kprobe_event(const char *str, char **group, char **event,
235 die("Failed to copy argument."); 246 die("Failed to copy argument.");
236 } 247 }
237 248
238end:
239 argv_free(argv); 249 argv_free(argv);
240} 250}
241 251
@@ -368,6 +378,10 @@ static void clear_probe_point(struct probe_point *pp)
368{ 378{
369 int i; 379 int i;
370 380
381 if (pp->event)
382 free(pp->event);
383 if (pp->group)
384 free(pp->group);
371 if (pp->function) 385 if (pp->function)
372 free(pp->function); 386 free(pp->function);
373 if (pp->file) 387 if (pp->file)
@@ -382,13 +396,13 @@ static void clear_probe_point(struct probe_point *pp)
382} 396}
383 397
384/* Show an event */ 398/* Show an event */
385static void show_perf_probe_event(const char *group, const char *event, 399static void show_perf_probe_event(const char *event, const char *place,
386 const char *place, struct probe_point *pp) 400 struct probe_point *pp)
387{ 401{
388 int i, ret; 402 int i, ret;
389 char buf[128]; 403 char buf[128];
390 404
391 ret = e_snprintf(buf, 128, "%s:%s", group, event); 405 ret = e_snprintf(buf, 128, "%s:%s", pp->group, event);
392 if (ret < 0) 406 if (ret < 0)
393 die("Failed to copy event: %s", strerror(-ret)); 407 die("Failed to copy event: %s", strerror(-ret));
394 printf(" %-40s (on %s", buf, place); 408 printf(" %-40s (on %s", buf, place);
@@ -405,7 +419,6 @@ static void show_perf_probe_event(const char *group, const char *event,
405void show_perf_probe_events(void) 419void show_perf_probe_events(void)
406{ 420{
407 int fd, nr; 421 int fd, nr;
408 char *group, *event;
409 struct probe_point pp; 422 struct probe_point pp;
410 struct strlist *rawlist; 423 struct strlist *rawlist;
411 struct str_node *ent; 424 struct str_node *ent;
@@ -415,16 +428,14 @@ void show_perf_probe_events(void)
415 close(fd); 428 close(fd);
416 429
417 strlist__for_each(ent, rawlist) { 430 strlist__for_each(ent, rawlist) {
418 parse_trace_kprobe_event(ent->s, &group, &event, &pp); 431 parse_trace_kprobe_event(ent->s, &pp);
419 /* Synthesize only event probe point */ 432 /* Synthesize only event probe point */
420 nr = pp.nr_args; 433 nr = pp.nr_args;
421 pp.nr_args = 0; 434 pp.nr_args = 0;
422 synthesize_perf_probe_event(&pp); 435 synthesize_perf_probe_event(&pp);
423 pp.nr_args = nr; 436 pp.nr_args = nr;
424 /* Show an event */ 437 /* Show an event */
425 show_perf_probe_event(group, event, pp.probes[0], &pp); 438 show_perf_probe_event(pp.event, pp.probes[0], &pp);
426 free(group);
427 free(event);
428 clear_probe_point(&pp); 439 clear_probe_point(&pp);
429 } 440 }
430 441
@@ -434,24 +445,25 @@ void show_perf_probe_events(void)
434/* Get current perf-probe event names */ 445/* Get current perf-probe event names */
435static struct strlist *get_perf_event_names(int fd, bool include_group) 446static struct strlist *get_perf_event_names(int fd, bool include_group)
436{ 447{
437 char *group, *event;
438 char buf[128]; 448 char buf[128];
439 struct strlist *sl, *rawlist; 449 struct strlist *sl, *rawlist;
440 struct str_node *ent; 450 struct str_node *ent;
451 struct probe_point pp;
441 452
453 memset(&pp, 0, sizeof(pp));
442 rawlist = get_trace_kprobe_event_rawlist(fd); 454 rawlist = get_trace_kprobe_event_rawlist(fd);
443 455
444 sl = strlist__new(true, NULL); 456 sl = strlist__new(true, NULL);
445 strlist__for_each(ent, rawlist) { 457 strlist__for_each(ent, rawlist) {
446 parse_trace_kprobe_event(ent->s, &group, &event, NULL); 458 parse_trace_kprobe_event(ent->s, &pp);
447 if (include_group) { 459 if (include_group) {
448 if (e_snprintf(buf, 128, "%s:%s", group, event) < 0) 460 if (e_snprintf(buf, 128, "%s:%s", pp.group,
461 pp.event) < 0)
449 die("Failed to copy group:event name."); 462 die("Failed to copy group:event name.");
450 strlist__add(sl, buf); 463 strlist__add(sl, buf);
451 } else 464 } else
452 strlist__add(sl, event); 465 strlist__add(sl, pp.event);
453 free(group); 466 clear_probe_point(&pp);
454 free(event);
455 } 467 }
456 468
457 strlist__delete(rawlist); 469 strlist__delete(rawlist);
@@ -507,19 +519,23 @@ void add_trace_kprobe_events(struct probe_point *probes, int nr_probes)
507 519
508 for (j = 0; j < nr_probes; j++) { 520 for (j = 0; j < nr_probes; j++) {
509 pp = probes + j; 521 pp = probes + j;
522 if (!pp->event)
523 pp->event = strdup(pp->function);
524 if (!pp->group)
525 pp->group = strdup(PERFPROBE_GROUP);
526 DIE_IF(!pp->event || !pp->group);
510 for (i = 0; i < pp->found; i++) { 527 for (i = 0; i < pp->found; i++) {
511 /* Get an unused new event name */ 528 /* Get an unused new event name */
512 get_new_event_name(event, 64, pp->function, namelist); 529 get_new_event_name(event, 64, pp->event, namelist);
513 snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n", 530 snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n",
514 pp->retprobe ? 'r' : 'p', 531 pp->retprobe ? 'r' : 'p',
515 PERFPROBE_GROUP, event, 532 pp->group, event,
516 pp->probes[i]); 533 pp->probes[i]);
517 write_trace_kprobe_event(fd, buf); 534 write_trace_kprobe_event(fd, buf);
518 printf("Added new event:\n"); 535 printf("Added new event:\n");
519 /* Get the first parameter (probe-point) */ 536 /* Get the first parameter (probe-point) */
520 sscanf(pp->probes[i], "%s", buf); 537 sscanf(pp->probes[i], "%s", buf);
521 show_perf_probe_event(PERFPROBE_GROUP, event, 538 show_perf_probe_event(event, buf, pp);
522 buf, pp);
523 /* Add added event name to namelist */ 539 /* Add added event name to namelist */
524 strlist__add(namelist, event); 540 strlist__add(namelist, event);
525 } 541 }
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 028575b5fc3b..8bb22f5246cc 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -8,8 +8,7 @@
8extern void parse_perf_probe_event(const char *str, struct probe_point *pp, 8extern void parse_perf_probe_event(const char *str, struct probe_point *pp,
9 bool *need_dwarf); 9 bool *need_dwarf);
10extern int synthesize_perf_probe_event(struct probe_point *pp); 10extern int synthesize_perf_probe_event(struct probe_point *pp);
11extern void parse_trace_kprobe_event(const char *str, char **group, 11extern void parse_trace_kprobe_event(const char *str, struct probe_point *pp);
12 char **event, struct probe_point *pp);
13extern int synthesize_trace_kprobe_event(struct probe_point *pp); 12extern int synthesize_trace_kprobe_event(struct probe_point *pp);
14extern void add_trace_kprobe_events(struct probe_point *probes, int nr_probes); 13extern void add_trace_kprobe_events(struct probe_point *probes, int nr_probes);
15extern void del_trace_kprobe_events(struct strlist *dellist); 14extern void del_trace_kprobe_events(struct strlist *dellist);
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index bdebca6697d2..5e4050ce2963 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -12,6 +12,9 @@ static inline int is_c_varname(const char *name)
12} 12}
13 13
14struct probe_point { 14struct probe_point {
15 char *event; /* Event name */
16 char *group; /* Event group */
17
15 /* Inputs */ 18 /* Inputs */
16 char *file; /* File name */ 19 char *file; /* File name */
17 int line; /* Line number */ 20 int line; /* Line number */