aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-probe.c33
-rw-r--r--tools/perf/util/probe-event.c69
-rw-r--r--tools/perf/util/probe-event.h1
3 files changed, 96 insertions, 7 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 1c97e133a3f4..5a47c1e11f77 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -35,6 +35,7 @@
35#include "perf.h" 35#include "perf.h"
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/event.h" 39#include "util/event.h"
39#include "util/debug.h" 40#include "util/debug.h"
40#include "util/parse-options.h" 41#include "util/parse-options.h"
@@ -61,6 +62,7 @@ static struct {
61 int need_dwarf; 62 int need_dwarf;
62 int nr_probe; 63 int nr_probe;
63 struct probe_point probes[MAX_PROBES]; 64 struct probe_point probes[MAX_PROBES];
65 struct strlist *dellist;
64} session; 66} session;
65 67
66static bool listing; 68static bool listing;
@@ -107,6 +109,17 @@ static int opt_add_probe_event(const struct option *opt __used,
107 return 0; 109 return 0;
108} 110}
109 111
112static int opt_del_probe_event(const struct option *opt __used,
113 const char *str, int unset __used)
114{
115 if (str) {
116 if (!session.dellist)
117 session.dellist = strlist__new(true, NULL);
118 strlist__add(session.dellist, str);
119 }
120 return 0;
121}
122
110#ifndef NO_LIBDWARF 123#ifndef NO_LIBDWARF
111static int open_default_vmlinux(void) 124static int open_default_vmlinux(void)
112{ 125{
@@ -141,6 +154,7 @@ static int open_default_vmlinux(void)
141static const char * const probe_usage[] = { 154static const char * const probe_usage[] = {
142 "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]", 155 "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
143 "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]", 156 "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
157 "perf probe [<options>] --del '[GROUP:]EVENT' ...",
144 "perf probe --list", 158 "perf probe --list",
145 NULL 159 NULL
146}; 160};
@@ -152,7 +166,9 @@ static const struct option options[] = {
152 OPT_STRING('k', "vmlinux", &session.vmlinux, "file", 166 OPT_STRING('k', "vmlinux", &session.vmlinux, "file",
153 "vmlinux/module pathname"), 167 "vmlinux/module pathname"),
154#endif 168#endif
155 OPT_BOOLEAN('l', "list", &listing, "list up current probes"), 169 OPT_BOOLEAN('l', "list", &listing, "list up current probe events"),
170 OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
171 opt_del_probe_event),
156 OPT_CALLBACK('a', "add", NULL, 172 OPT_CALLBACK('a', "add", NULL,
157#ifdef NO_LIBDWARF 173#ifdef NO_LIBDWARF
158 "FUNC[+OFFS|%return] [ARG ...]", 174 "FUNC[+OFFS|%return] [ARG ...]",
@@ -191,15 +207,26 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
191 if (argc > 0) 207 if (argc > 0)
192 parse_probe_event_argv(argc, argv); 208 parse_probe_event_argv(argc, argv);
193 209
194 if ((session.nr_probe == 0 && !listing) || 210 if ((session.nr_probe == 0 && !session.dellist && !listing))
195 (session.nr_probe != 0 && listing))
196 usage_with_options(probe_usage, options); 211 usage_with_options(probe_usage, options);
197 212
198 if (listing) { 213 if (listing) {
214 if (session.nr_probe != 0 || session.dellist) {
215 pr_warning(" Error: Don't use --list with"
216 " --add/--del.\n");
217 usage_with_options(probe_usage, options);
218 }
199 show_perf_probe_events(); 219 show_perf_probe_events();
200 return 0; 220 return 0;
201 } 221 }
202 222
223 if (session.dellist) {
224 del_trace_kprobe_events(session.dellist);
225 strlist__delete(session.dellist);
226 if (session.nr_probe == 0)
227 return 0;
228 }
229
203 if (session.need_dwarf) 230 if (session.need_dwarf)
204#ifdef NO_LIBDWARF 231#ifdef NO_LIBDWARF
205 die("Debuginfo-analysis is not supported"); 232 die("Debuginfo-analysis is not supported");
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 31beedcf61c1..9480d9941cc0 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -430,10 +430,11 @@ void show_perf_probe_events(void)
430} 430}
431 431
432/* Get current perf-probe event names */ 432/* Get current perf-probe event names */
433static struct strlist *get_perf_event_names(int fd) 433static struct strlist *get_perf_event_names(int fd, bool include_group)
434{ 434{
435 unsigned int i; 435 unsigned int i;
436 char *group, *event; 436 char *group, *event;
437 char buf[128];
437 struct strlist *sl, *rawlist; 438 struct strlist *sl, *rawlist;
438 struct str_node *ent; 439 struct str_node *ent;
439 440
@@ -443,7 +444,12 @@ static struct strlist *get_perf_event_names(int fd)
443 for (i = 0; i < strlist__nr_entries(rawlist); i++) { 444 for (i = 0; i < strlist__nr_entries(rawlist); i++) {
444 ent = strlist__entry(rawlist, i); 445 ent = strlist__entry(rawlist, i);
445 parse_trace_kprobe_event(ent->s, &group, &event, NULL); 446 parse_trace_kprobe_event(ent->s, &group, &event, NULL);
446 strlist__add(sl, event); 447 if (include_group) {
448 if (e_snprintf(buf, 128, "%s:%s", group, event) < 0)
449 die("Failed to copy group:event name.");
450 strlist__add(sl, buf);
451 } else
452 strlist__add(sl, event);
447 free(group); 453 free(group);
448 free(event); 454 free(event);
449 } 455 }
@@ -457,9 +463,10 @@ static void write_trace_kprobe_event(int fd, const char *buf)
457{ 463{
458 int ret; 464 int ret;
459 465
466 pr_debug("Writing event: %s\n", buf);
460 ret = write(fd, buf, strlen(buf)); 467 ret = write(fd, buf, strlen(buf));
461 if (ret <= 0) 468 if (ret <= 0)
462 die("Failed to create event."); 469 die("Failed to write event: %s", strerror(errno));
463} 470}
464 471
465static void get_new_event_name(char *buf, size_t len, const char *base, 472static void get_new_event_name(char *buf, size_t len, const char *base,
@@ -496,7 +503,7 @@ void add_trace_kprobe_events(struct probe_point *probes, int nr_probes)
496 503
497 fd = open_kprobe_events(O_RDWR, O_APPEND); 504 fd = open_kprobe_events(O_RDWR, O_APPEND);
498 /* Get current event names */ 505 /* Get current event names */
499 namelist = get_perf_event_names(fd); 506 namelist = get_perf_event_names(fd, false);
500 507
501 for (j = 0; j < nr_probes; j++) { 508 for (j = 0; j < nr_probes; j++) {
502 pp = probes + j; 509 pp = probes + j;
@@ -524,3 +531,57 @@ void add_trace_kprobe_events(struct probe_point *probes, int nr_probes)
524 strlist__delete(namelist); 531 strlist__delete(namelist);
525 close(fd); 532 close(fd);
526} 533}
534
535static void del_trace_kprobe_event(int fd, const char *group,
536 const char *event, struct strlist *namelist)
537{
538 char buf[128];
539
540 if (e_snprintf(buf, 128, "%s:%s", group, event) < 0)
541 die("Failed to copy event.");
542 if (!strlist__has_entry(namelist, buf)) {
543 pr_warning("Warning: event \"%s\" is not found.\n", buf);
544 return;
545 }
546 /* Convert from perf-probe event to trace-kprobe event */
547 if (e_snprintf(buf, 128, "-:%s/%s", group, event) < 0)
548 die("Failed to copy event.");
549
550 write_trace_kprobe_event(fd, buf);
551 printf("Remove event: %s:%s\n", group, event);
552}
553
554void del_trace_kprobe_events(struct strlist *dellist)
555{
556 int fd;
557 unsigned int i;
558 const char *group, *event;
559 char *p, *str;
560 struct str_node *ent;
561 struct strlist *namelist;
562
563 fd = open_kprobe_events(O_RDWR, O_APPEND);
564 /* Get current event names */
565 namelist = get_perf_event_names(fd, true);
566
567 for (i = 0; i < strlist__nr_entries(dellist); i++) {
568 ent = strlist__entry(dellist, i);
569 str = strdup(ent->s);
570 if (!str)
571 die("Failed to copy event.");
572 p = strchr(str, ':');
573 if (p) {
574 group = str;
575 *p = '\0';
576 event = p + 1;
577 } else {
578 group = PERFPROBE_GROUP;
579 event = str;
580 }
581 del_trace_kprobe_event(fd, group, event, namelist);
582 free(str);
583 }
584 strlist__delete(namelist);
585 close(fd);
586}
587
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 0c6fe56fe38a..f752159124ae 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -10,6 +10,7 @@ extern void parse_trace_kprobe_event(const char *str, char **group,
10 char **event, struct probe_point *pp); 10 char **event, struct probe_point *pp);
11extern int synthesize_trace_kprobe_event(struct probe_point *pp); 11extern 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 del_trace_kprobe_events(struct strlist *dellist);
13extern void show_perf_probe_events(void); 14extern void show_perf_probe_events(void);
14 15
15/* Maximum index number of event-name postfix */ 16/* Maximum index number of event-name postfix */