aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-04-27 05:16:54 -0400
committerIngo Molnar <mingo@elte.hu>2010-04-27 05:16:54 -0400
commit462b04e28a7ec1339c892117c3f20a40e55d0e83 (patch)
tree5ea38f3227c761fa936b293afa52c26a660bd6c7
parentcfadf9d4ac4be940595ab73d3def24c23c8b875f (diff)
parentf93830fbb06b67848c762f2177c06cc3cbb97deb (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.txt3
-rw-r--r--tools/perf/Makefile2
-rw-r--r--tools/perf/builtin-probe.c9
-rw-r--r--tools/perf/util/probe-event.c34
-rw-r--r--tools/perf/util/probe-event.h4
-rw-r--r--tools/perf/util/probe-finder.c15
-rw-r--r--tools/perf/util/probe-finder.h6
-rw-r--r--tools/perf/util/symbol.c1
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
65PROBE SYNTAX 68PROBE SYNTAX
66------------ 69------------
67Probe points are defined by following syntax. 70Probe 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
505ifndef NO_DWARF 505ifndef NO_DWARF
506ifneq ($(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) 506ifneq ($(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
509endif # Dwarf support 509endif # Dwarf support
510endif # NO_DWARF 510endif # 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", &params.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 */
152static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, 152static 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
319static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, 321static 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
1409static int convert_to_kprobe_trace_events(struct perf_probe_event *pev, 1412static 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
1488int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, 1492int 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);
115extern int parse_line_range_desc(const char *cmd, struct line_range *lr); 115extern int parse_line_range_desc(const char *cmd, struct line_range *lr);
116 116
117 117
118extern int add_perf_probe_events(struct perf_probe_event *pevs, int ntevs, 118extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
119 bool force_add); 119 bool force_add, int max_probe_points);
120extern int del_perf_probe_events(struct strlist *dellist); 120extern int del_perf_probe_events(struct strlist *dellist);
121extern int show_perf_probe_events(void); 121extern int show_perf_probe_events(void);
122extern int show_line_range(struct line_range *lr); 122extern 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 */
932int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, 935int 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 */
20extern int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, 20extern 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 */
24extern int find_perf_probe_point(int fd, unsigned long addr, 25extern 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);
32struct probe_finder { 33struct 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;