aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/probe-event.c67
-rw-r--r--tools/perf/util/probe-event.h3
2 files changed, 56 insertions, 14 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 7f4f288c642e..e42f3acc9a7e 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -403,6 +403,29 @@ void show_perf_probe_events(void)
403 strlist__delete(rawlist); 403 strlist__delete(rawlist);
404} 404}
405 405
406/* Get current perf-probe event names */
407static struct strlist *get_perf_event_names(int fd)
408{
409 unsigned int i;
410 char *group, *event;
411 struct strlist *sl, *rawlist;
412 struct str_node *ent;
413
414 rawlist = get_trace_kprobe_event_rawlist(fd);
415
416 sl = strlist__new(false, NULL);
417 for (i = 0; i < strlist__nr_entries(rawlist); i++) {
418 ent = strlist__entry(rawlist, i);
419 parse_trace_kprobe_event(ent->s, &group, &event, NULL);
420 strlist__add(sl, event);
421 free(group);
422 }
423
424 strlist__delete(rawlist);
425
426 return sl;
427}
428
406static int write_trace_kprobe_event(int fd, const char *buf) 429static int write_trace_kprobe_event(int fd, const char *buf)
407{ 430{
408 int ret; 431 int ret;
@@ -416,30 +439,46 @@ static int write_trace_kprobe_event(int fd, const char *buf)
416 return ret; 439 return ret;
417} 440}
418 441
442static void get_new_event_name(char *buf, size_t len, const char *base,
443 struct strlist *namelist)
444{
445 int i, ret;
446 for (i = 0; i < MAX_EVENT_INDEX; i++) {
447 ret = e_snprintf(buf, len, "%s_%d", base, i);
448 if (ret < 0)
449 die("snprintf() failed: %s", strerror(-ret));
450 if (!strlist__has_entry(namelist, buf))
451 break;
452 }
453 if (i == MAX_EVENT_INDEX)
454 die("Too many events are on the same function.");
455}
456
419void add_trace_kprobe_events(struct probe_point *probes, int nr_probes) 457void add_trace_kprobe_events(struct probe_point *probes, int nr_probes)
420{ 458{
421 int i, j, fd; 459 int i, j, fd;
422 struct probe_point *pp; 460 struct probe_point *pp;
423 char buf[MAX_CMDLEN]; 461 char buf[MAX_CMDLEN];
462 char event[64];
463 struct strlist *namelist;
424 464
425 fd = open_kprobe_events(O_WRONLY, O_APPEND); 465 fd = open_kprobe_events(O_RDWR, O_APPEND);
466 /* Get current event names */
467 namelist = get_perf_event_names(fd);
426 468
427 for (j = 0; j < nr_probes; j++) { 469 for (j = 0; j < nr_probes; j++) {
428 pp = probes + j; 470 pp = probes + j;
429 if (pp->found == 1) { 471 for (i = 0; i < pp->found; i++) {
430 snprintf(buf, MAX_CMDLEN, "%c:%s/%s_%x %s\n", 472 /* Get an unused new event name */
431 pp->retprobe ? 'r' : 'p', PERFPROBE_GROUP, 473 get_new_event_name(event, 64, pp->function, namelist);
432 pp->function, pp->offset, pp->probes[0]); 474 snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n",
475 pp->retprobe ? 'r' : 'p',
476 PERFPROBE_GROUP, event,
477 pp->probes[i]);
433 write_trace_kprobe_event(fd, buf); 478 write_trace_kprobe_event(fd, buf);
434 } else 479 /* Add added event name to namelist */
435 for (i = 0; i < pp->found; i++) { 480 strlist__add(namelist, event);
436 snprintf(buf, MAX_CMDLEN, "%c:%s/%s_%x_%d %s\n", 481 }
437 pp->retprobe ? 'r' : 'p',
438 PERFPROBE_GROUP,
439 pp->function, pp->offset, i,
440 pp->probes[i]);
441 write_trace_kprobe_event(fd, buf);
442 }
443 } 482 }
444 close(fd); 483 close(fd);
445} 484}
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 88db7d1a9472..0c6fe56fe38a 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -12,4 +12,7 @@ extern int synthesize_trace_kprobe_event(struct probe_point *pp);
12extern void add_trace_kprobe_events(struct probe_point *probes, int nr_probes); 12extern void add_trace_kprobe_events(struct probe_point *probes, int nr_probes);
13extern void show_perf_probe_events(void); 13extern void show_perf_probe_events(void);
14 14
15/* Maximum index number of event-name postfix */
16#define MAX_EVENT_INDEX 1024
17
15#endif /*_PROBE_EVENT_H */ 18#endif /*_PROBE_EVENT_H */