diff options
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/Documentation/perf-probe.txt | 3 | ||||
| -rw-r--r-- | tools/perf/builtin-probe.c | 9 | ||||
| -rw-r--r-- | tools/perf/util/probe-event.c | 17 | ||||
| -rw-r--r-- | tools/perf/util/probe-event.h | 4 | ||||
| -rw-r--r-- | tools/perf/util/probe-finder.c | 11 | ||||
| -rw-r--r-- | tools/perf/util/probe-finder.h | 6 |
6 files changed, 33 insertions, 17 deletions
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt index 63c25d304880..94a258c96a44 100644 --- a/tools/perf/Documentation/perf-probe.txt +++ b/tools/perf/Documentation/perf-probe.txt | |||
| @@ -62,6 +62,9 @@ OPTIONS | |||
| 62 | Dry run. With this option, --add and --del doesn't execute actual | 62 | Dry run. With this option, --add and --del doesn't execute actual |
| 63 | adding and removal operations. | 63 | adding and removal operations. |
| 64 | 64 | ||
| 65 | --max-probes:: | ||
| 66 | Set the maximum number of probe points for an event. Default is 128. | ||
| 67 | |||
| 65 | PROBE SYNTAX | 68 | PROBE SYNTAX |
| 66 | ------------ | 69 | ------------ |
| 67 | Probe points are defined by following syntax. | 70 | Probe points are defined by following syntax. |
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index c1e54035e8cf..61c6d70732c9 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
| @@ -54,6 +54,7 @@ static struct { | |||
| 54 | struct perf_probe_event events[MAX_PROBES]; | 54 | struct perf_probe_event events[MAX_PROBES]; |
| 55 | struct strlist *dellist; | 55 | struct strlist *dellist; |
| 56 | struct line_range line_range; | 56 | struct line_range line_range; |
| 57 | int max_probe_points; | ||
| 57 | } params; | 58 | } params; |
| 58 | 59 | ||
| 59 | 60 | ||
| @@ -179,6 +180,8 @@ static const struct option options[] = { | |||
| 179 | "file", "vmlinux pathname"), | 180 | "file", "vmlinux pathname"), |
| 180 | #endif | 181 | #endif |
| 181 | OPT__DRY_RUN(&probe_event_dry_run), | 182 | OPT__DRY_RUN(&probe_event_dry_run), |
| 183 | OPT_INTEGER('\0', "max-probes", ¶ms.max_probe_points, | ||
| 184 | "Set how many probe points can be found for a probe."), | ||
| 182 | OPT_END() | 185 | OPT_END() |
| 183 | }; | 186 | }; |
| 184 | 187 | ||
| @@ -200,6 +203,9 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) | |||
| 200 | } | 203 | } |
| 201 | } | 204 | } |
| 202 | 205 | ||
| 206 | if (params.max_probe_points == 0) | ||
| 207 | params.max_probe_points = MAX_PROBES; | ||
| 208 | |||
| 203 | if ((!params.nevents && !params.dellist && !params.list_events && | 209 | if ((!params.nevents && !params.dellist && !params.list_events && |
| 204 | !params.show_lines)) | 210 | !params.show_lines)) |
| 205 | usage_with_options(probe_usage, options); | 211 | usage_with_options(probe_usage, options); |
| @@ -246,7 +252,8 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) | |||
| 246 | 252 | ||
| 247 | if (params.nevents) { | 253 | if (params.nevents) { |
| 248 | ret = add_perf_probe_events(params.events, params.nevents, | 254 | ret = add_perf_probe_events(params.events, params.nevents, |
| 249 | params.force_add); | 255 | params.force_add, |
| 256 | params.max_probe_points); | ||
| 250 | if (ret < 0) { | 257 | if (ret < 0) { |
| 251 | pr_err(" Error: Failed to add events. (%d)\n", ret); | 258 | pr_err(" Error: Failed to add events. (%d)\n", ret); |
| 252 | return ret; | 259 | return ret; |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 5d3baec216e3..9ded38ced234 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
| @@ -150,7 +150,8 @@ static int convert_to_perf_probe_point(struct kprobe_trace_point *tp, | |||
| 150 | 150 | ||
| 151 | /* Try to find perf_probe_event with debuginfo */ | 151 | /* Try to find perf_probe_event with debuginfo */ |
| 152 | static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, | 152 | static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, |
| 153 | struct kprobe_trace_event **tevs) | 153 | struct kprobe_trace_event **tevs, |
| 154 | int max_tevs) | ||
| 154 | { | 155 | { |
| 155 | bool need_dwarf = perf_probe_event_need_dwarf(pev); | 156 | bool need_dwarf = perf_probe_event_need_dwarf(pev); |
| 156 | int fd, ntevs; | 157 | int fd, ntevs; |
| @@ -166,7 +167,7 @@ static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, | |||
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | /* Searching trace events corresponding to probe event */ | 169 | /* Searching trace events corresponding to probe event */ |
| 169 | ntevs = find_kprobe_trace_events(fd, pev, tevs); | 170 | ntevs = find_kprobe_trace_events(fd, pev, tevs, max_tevs); |
| 170 | close(fd); | 171 | close(fd); |
| 171 | 172 | ||
| 172 | if (ntevs > 0) { /* Succeeded to find trace events */ | 173 | if (ntevs > 0) { /* Succeeded to find trace events */ |
| @@ -318,7 +319,8 @@ static int convert_to_perf_probe_point(struct kprobe_trace_point *tp, | |||
| 318 | } | 319 | } |
| 319 | 320 | ||
| 320 | static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, | 321 | static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, |
| 321 | struct kprobe_trace_event **tevs __unused) | 322 | struct kprobe_trace_event **tevs __unused, |
| 323 | int max_tevs __unused) | ||
| 322 | { | 324 | { |
| 323 | if (perf_probe_event_need_dwarf(pev)) { | 325 | if (perf_probe_event_need_dwarf(pev)) { |
| 324 | pr_warning("Debuginfo-analysis is not supported.\n"); | 326 | pr_warning("Debuginfo-analysis is not supported.\n"); |
| @@ -1408,14 +1410,15 @@ static int __add_kprobe_trace_events(struct perf_probe_event *pev, | |||
| 1408 | } | 1410 | } |
| 1409 | 1411 | ||
| 1410 | static int convert_to_kprobe_trace_events(struct perf_probe_event *pev, | 1412 | static int convert_to_kprobe_trace_events(struct perf_probe_event *pev, |
| 1411 | struct kprobe_trace_event **tevs) | 1413 | struct kprobe_trace_event **tevs, |
| 1414 | int max_tevs) | ||
| 1412 | { | 1415 | { |
| 1413 | struct symbol *sym; | 1416 | struct symbol *sym; |
| 1414 | int ret = 0, i; | 1417 | int ret = 0, i; |
| 1415 | struct kprobe_trace_event *tev; | 1418 | struct kprobe_trace_event *tev; |
| 1416 | 1419 | ||
| 1417 | /* Convert perf_probe_event with debuginfo */ | 1420 | /* Convert perf_probe_event with debuginfo */ |
| 1418 | ret = try_to_find_kprobe_trace_events(pev, tevs); | 1421 | ret = try_to_find_kprobe_trace_events(pev, tevs, max_tevs); |
| 1419 | if (ret != 0) | 1422 | if (ret != 0) |
| 1420 | return ret; | 1423 | return ret; |
| 1421 | 1424 | ||
| @@ -1487,7 +1490,7 @@ struct __event_package { | |||
| 1487 | }; | 1490 | }; |
| 1488 | 1491 | ||
| 1489 | int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | 1492 | int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, |
| 1490 | bool force_add) | 1493 | bool force_add, int max_tevs) |
| 1491 | { | 1494 | { |
| 1492 | int i, j, ret; | 1495 | int i, j, ret; |
| 1493 | struct __event_package *pkgs; | 1496 | struct __event_package *pkgs; |
| @@ -1506,7 +1509,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | |||
| 1506 | pkgs[i].pev = &pevs[i]; | 1509 | pkgs[i].pev = &pevs[i]; |
| 1507 | /* Convert with or without debuginfo */ | 1510 | /* Convert with or without debuginfo */ |
| 1508 | ret = convert_to_kprobe_trace_events(pkgs[i].pev, | 1511 | ret = convert_to_kprobe_trace_events(pkgs[i].pev, |
| 1509 | &pkgs[i].tevs); | 1512 | &pkgs[i].tevs, max_tevs); |
| 1510 | if (ret < 0) | 1513 | if (ret < 0) |
| 1511 | goto end; | 1514 | goto end; |
| 1512 | pkgs[i].ntevs = ret; | 1515 | pkgs[i].ntevs = ret; |
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index e7ff0d02c0d4..e9db1a214ca4 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h | |||
| @@ -115,8 +115,8 @@ extern void clear_kprobe_trace_event(struct kprobe_trace_event *tev); | |||
| 115 | extern int parse_line_range_desc(const char *cmd, struct line_range *lr); | 115 | extern int parse_line_range_desc(const char *cmd, struct line_range *lr); |
| 116 | 116 | ||
| 117 | 117 | ||
| 118 | extern int add_perf_probe_events(struct perf_probe_event *pevs, int ntevs, | 118 | extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, |
| 119 | bool force_add); | 119 | bool force_add, int max_probe_points); |
| 120 | extern int del_perf_probe_events(struct strlist *dellist); | 120 | extern int del_perf_probe_events(struct strlist *dellist); |
| 121 | extern int show_perf_probe_events(void); | 121 | extern int show_perf_probe_events(void); |
| 122 | extern int show_line_range(struct line_range *lr); | 122 | extern int show_line_range(struct line_range *lr); |
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 0d795bc3e1a8..562b1443e785 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
| @@ -626,8 +626,9 @@ static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) | |||
| 626 | Dwarf_Attribute fb_attr; | 626 | Dwarf_Attribute fb_attr; |
| 627 | size_t nops; | 627 | size_t nops; |
| 628 | 628 | ||
| 629 | if (pf->ntevs == MAX_PROBES) { | 629 | if (pf->ntevs == pf->max_tevs) { |
| 630 | pr_warning("Too many( > %d) probe point found.\n", MAX_PROBES); | 630 | pr_warning("Too many( > %d) probe point found.\n", |
| 631 | pf->max_tevs); | ||
| 631 | return -ERANGE; | 632 | return -ERANGE; |
| 632 | } | 633 | } |
| 633 | tev = &pf->tevs[pf->ntevs++]; | 634 | tev = &pf->tevs[pf->ntevs++]; |
| @@ -932,9 +933,9 @@ static int find_probe_point_by_func(struct probe_finder *pf) | |||
| 932 | 933 | ||
| 933 | /* Find kprobe_trace_events specified by perf_probe_event from debuginfo */ | 934 | /* Find kprobe_trace_events specified by perf_probe_event from debuginfo */ |
| 934 | int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, | 935 | int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, |
| 935 | struct kprobe_trace_event **tevs) | 936 | struct kprobe_trace_event **tevs, int max_tevs) |
| 936 | { | 937 | { |
| 937 | struct probe_finder pf = {.pev = pev}; | 938 | struct probe_finder pf = {.pev = pev, .max_tevs = max_tevs}; |
| 938 | struct perf_probe_point *pp = &pev->point; | 939 | struct perf_probe_point *pp = &pev->point; |
| 939 | Dwarf_Off off, noff; | 940 | Dwarf_Off off, noff; |
| 940 | size_t cuhl; | 941 | size_t cuhl; |
| @@ -942,7 +943,7 @@ int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, | |||
| 942 | Dwarf *dbg; | 943 | Dwarf *dbg; |
| 943 | int ret = 0; | 944 | int ret = 0; |
| 944 | 945 | ||
| 945 | pf.tevs = zalloc(sizeof(struct kprobe_trace_event) * MAX_PROBES); | 946 | pf.tevs = zalloc(sizeof(struct kprobe_trace_event) * max_tevs); |
| 946 | if (pf.tevs == NULL) | 947 | if (pf.tevs == NULL) |
| 947 | return -ENOMEM; | 948 | return -ENOMEM; |
| 948 | *tevs = pf.tevs; | 949 | *tevs = pf.tevs; |
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index 310ce897229c..66f1980e3855 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h | |||
| @@ -18,7 +18,8 @@ static inline int is_c_varname(const char *name) | |||
| 18 | #ifdef DWARF_SUPPORT | 18 | #ifdef DWARF_SUPPORT |
| 19 | /* Find kprobe_trace_events specified by perf_probe_event from debuginfo */ | 19 | /* Find kprobe_trace_events specified by perf_probe_event from debuginfo */ |
| 20 | extern int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, | 20 | extern int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, |
| 21 | struct kprobe_trace_event **tevs); | 21 | struct kprobe_trace_event **tevs, |
| 22 | int max_tevs); | ||
| 22 | 23 | ||
| 23 | /* Find a perf_probe_point from debuginfo */ | 24 | /* Find a perf_probe_point from debuginfo */ |
| 24 | extern int find_perf_probe_point(int fd, unsigned long addr, | 25 | extern int find_perf_probe_point(int fd, unsigned long addr, |
| @@ -32,7 +33,8 @@ extern int find_line_range(int fd, struct line_range *lr); | |||
| 32 | struct probe_finder { | 33 | struct probe_finder { |
| 33 | struct perf_probe_event *pev; /* Target probe event */ | 34 | struct perf_probe_event *pev; /* Target probe event */ |
| 34 | struct kprobe_trace_event *tevs; /* Result trace events */ | 35 | struct kprobe_trace_event *tevs; /* Result trace events */ |
| 35 | int ntevs; /* number of trace events */ | 36 | int ntevs; /* Number of trace events */ |
| 37 | int max_tevs; /* Max number of trace events */ | ||
| 36 | 38 | ||
| 37 | /* For function searching */ | 39 | /* For function searching */ |
| 38 | int lno; /* Line number */ | 40 | int lno; /* Line number */ |
