diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-04-27 05:16:54 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-04-27 05:16:54 -0400 |
commit | 462b04e28a7ec1339c892117c3f20a40e55d0e83 (patch) | |
tree | 5ea38f3227c761fa936b293afa52c26a660bd6c7 | |
parent | cfadf9d4ac4be940595ab73d3def24c23c8b875f (diff) | |
parent | f93830fbb06b67848c762f2177c06cc3cbb97deb (diff) |
Merge branch 'perf' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
-rw-r--r-- | tools/perf/Documentation/perf-probe.txt | 3 | ||||
-rw-r--r-- | tools/perf/Makefile | 2 | ||||
-rw-r--r-- | tools/perf/builtin-probe.c | 9 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 34 | ||||
-rw-r--r-- | tools/perf/util/probe-event.h | 4 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.c | 15 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.h | 6 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 1 |
8 files changed, 48 insertions, 26 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/Makefile b/tools/perf/Makefile index e8bf2e1ab497..3ac6b677becd 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -504,7 +504,7 @@ PERFLIBS = $(LIB_FILE) | |||
504 | 504 | ||
505 | ifndef NO_DWARF | 505 | ifndef NO_DWARF |
506 | ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) | 506 | ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) |
507 | msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev); | 507 | msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/libdw-dev); |
508 | NO_DWARF := 1 | 508 | NO_DWARF := 1 |
509 | endif # Dwarf support | 509 | endif # Dwarf support |
510 | endif # NO_DWARF | 510 | endif # NO_DWARF |
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 4fb480367c3e..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 */ |
@@ -180,15 +181,16 @@ static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, | |||
180 | return -ENOENT; | 181 | return -ENOENT; |
181 | } | 182 | } |
182 | /* Error path : ntevs < 0 */ | 183 | /* Error path : ntevs < 0 */ |
183 | if (need_dwarf) { | 184 | pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs); |
184 | if (ntevs == -EBADF) | 185 | if (ntevs == -EBADF) { |
185 | pr_warning("No dwarf info found in the vmlinux - " | 186 | pr_warning("Warning: No dwarf info found in the vmlinux - " |
186 | "please rebuild with CONFIG_DEBUG_INFO=y.\n"); | 187 | "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n"); |
187 | return ntevs; | 188 | if (!need_dwarf) { |
189 | pr_debug("Trying to use symbols.\nn"); | ||
190 | return 0; | ||
191 | } | ||
188 | } | 192 | } |
189 | pr_debug("An error occurred in debuginfo analysis." | 193 | return ntevs; |
190 | " Try to use symbols.\n"); | ||
191 | return 0; | ||
192 | } | 194 | } |
193 | 195 | ||
194 | #define LINEBUF_SIZE 256 | 196 | #define LINEBUF_SIZE 256 |
@@ -317,7 +319,8 @@ static int convert_to_perf_probe_point(struct kprobe_trace_point *tp, | |||
317 | } | 319 | } |
318 | 320 | ||
319 | 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, |
320 | struct kprobe_trace_event **tevs __unused) | 322 | struct kprobe_trace_event **tevs __unused, |
323 | int max_tevs __unused) | ||
321 | { | 324 | { |
322 | if (perf_probe_event_need_dwarf(pev)) { | 325 | if (perf_probe_event_need_dwarf(pev)) { |
323 | pr_warning("Debuginfo-analysis is not supported.\n"); | 326 | pr_warning("Debuginfo-analysis is not supported.\n"); |
@@ -1407,14 +1410,15 @@ static int __add_kprobe_trace_events(struct perf_probe_event *pev, | |||
1407 | } | 1410 | } |
1408 | 1411 | ||
1409 | 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, |
1410 | struct kprobe_trace_event **tevs) | 1413 | struct kprobe_trace_event **tevs, |
1414 | int max_tevs) | ||
1411 | { | 1415 | { |
1412 | struct symbol *sym; | 1416 | struct symbol *sym; |
1413 | int ret = 0, i; | 1417 | int ret = 0, i; |
1414 | struct kprobe_trace_event *tev; | 1418 | struct kprobe_trace_event *tev; |
1415 | 1419 | ||
1416 | /* Convert perf_probe_event with debuginfo */ | 1420 | /* Convert perf_probe_event with debuginfo */ |
1417 | ret = try_to_find_kprobe_trace_events(pev, tevs); | 1421 | ret = try_to_find_kprobe_trace_events(pev, tevs, max_tevs); |
1418 | if (ret != 0) | 1422 | if (ret != 0) |
1419 | return ret; | 1423 | return ret; |
1420 | 1424 | ||
@@ -1486,7 +1490,7 @@ struct __event_package { | |||
1486 | }; | 1490 | }; |
1487 | 1491 | ||
1488 | 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, |
1489 | bool force_add) | 1493 | bool force_add, int max_tevs) |
1490 | { | 1494 | { |
1491 | int i, j, ret; | 1495 | int i, j, ret; |
1492 | struct __event_package *pkgs; | 1496 | struct __event_package *pkgs; |
@@ -1505,7 +1509,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | |||
1505 | pkgs[i].pev = &pevs[i]; | 1509 | pkgs[i].pev = &pevs[i]; |
1506 | /* Convert with or without debuginfo */ | 1510 | /* Convert with or without debuginfo */ |
1507 | ret = convert_to_kprobe_trace_events(pkgs[i].pev, | 1511 | ret = convert_to_kprobe_trace_events(pkgs[i].pev, |
1508 | &pkgs[i].tevs); | 1512 | &pkgs[i].tevs, max_tevs); |
1509 | if (ret < 0) | 1513 | if (ret < 0) |
1510 | goto end; | 1514 | goto end; |
1511 | 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 e7ee52fd0e09..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++]; |
@@ -871,6 +872,8 @@ static int probe_point_inline_cb(Dwarf_Die *in_die, void *data) | |||
871 | (uintmax_t)pf->addr); | 872 | (uintmax_t)pf->addr); |
872 | 873 | ||
873 | param->retval = convert_probe_point(in_die, pf); | 874 | param->retval = convert_probe_point(in_die, pf); |
875 | if (param->retval < 0) | ||
876 | return DWARF_CB_ABORT; | ||
874 | } | 877 | } |
875 | 878 | ||
876 | return DWARF_CB_OK; | 879 | return DWARF_CB_OK; |
@@ -930,9 +933,9 @@ static int find_probe_point_by_func(struct probe_finder *pf) | |||
930 | 933 | ||
931 | /* Find kprobe_trace_events specified by perf_probe_event from debuginfo */ | 934 | /* Find kprobe_trace_events specified by perf_probe_event from debuginfo */ |
932 | 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, |
933 | struct kprobe_trace_event **tevs) | 936 | struct kprobe_trace_event **tevs, int max_tevs) |
934 | { | 937 | { |
935 | struct probe_finder pf = {.pev = pev}; | 938 | struct probe_finder pf = {.pev = pev, .max_tevs = max_tevs}; |
936 | struct perf_probe_point *pp = &pev->point; | 939 | struct perf_probe_point *pp = &pev->point; |
937 | Dwarf_Off off, noff; | 940 | Dwarf_Off off, noff; |
938 | size_t cuhl; | 941 | size_t cuhl; |
@@ -940,7 +943,7 @@ int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, | |||
940 | Dwarf *dbg; | 943 | Dwarf *dbg; |
941 | int ret = 0; | 944 | int ret = 0; |
942 | 945 | ||
943 | pf.tevs = zalloc(sizeof(struct kprobe_trace_event) * MAX_PROBES); | 946 | pf.tevs = zalloc(sizeof(struct kprobe_trace_event) * max_tevs); |
944 | if (pf.tevs == NULL) | 947 | if (pf.tevs == NULL) |
945 | return -ENOMEM; | 948 | return -ENOMEM; |
946 | *tevs = pf.tevs; | 949 | *tevs = pf.tevs; |
@@ -1106,6 +1109,8 @@ static int line_range_funcdecl_cb(Dwarf_Die *sp_die, void *data) | |||
1106 | return DWARF_CB_OK; | 1109 | return DWARF_CB_OK; |
1107 | 1110 | ||
1108 | param->retval = line_range_add_line(src, lineno, lf->lr); | 1111 | param->retval = line_range_add_line(src, lineno, lf->lr); |
1112 | if (param->retval < 0) | ||
1113 | return DWARF_CB_ABORT; | ||
1109 | return DWARF_CB_OK; | 1114 | return DWARF_CB_OK; |
1110 | } | 1115 | } |
1111 | 1116 | ||
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 */ |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e782e7db16c5..e77c33a11de3 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -189,6 +189,7 @@ struct dso *dso__new(const char *name) | |||
189 | self->sorted_by_name = 0; | 189 | self->sorted_by_name = 0; |
190 | self->has_build_id = 0; | 190 | self->has_build_id = 0; |
191 | self->kernel = DSO_TYPE_USER; | 191 | self->kernel = DSO_TYPE_USER; |
192 | INIT_LIST_HEAD(&self->node); | ||
192 | } | 193 | } |
193 | 194 | ||
194 | return self; | 195 | return self; |