diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2010-04-21 15:56:40 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-04-26 14:35:20 -0400 |
commit | ef4a356574426877d569f8b6579325537eb7909b (patch) | |
tree | 0416c4ab1740a5ff6a07c01eee3e371128881110 /tools | |
parent | 5d1ee0413c8e2e0aa48510b1edfb3c4d2d43455b (diff) |
perf probe: Add --max-probes option
Add --max-probes option to change the maximum limit of
findable probe points per event, since inlined function can be
expanded into thousands of probe points. Default value is 128.
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Suggested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
LKML-Reference: <20100421195640.24664.62984.stgit@localhost6.localdomain6>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-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 */ |