aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-11-18 00:56:48 -0500
committerIngo Molnar <mingo@kernel.org>2015-11-18 00:56:48 -0500
commite15bf88a44d1fcb685754b2868b1cd28927af3aa (patch)
tree9c4f25db4edd2a42a9372366f4e6230e4a7a4037
parent2a49f02a7580d23802ea0e16ceb6d5523ab21aa8 (diff)
parent092b1f0b5f9f797812da0de927c3aa26acbe8762 (diff)
Merge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/urgent fixes from Arnaldo Carvalho de Melo: - Do not change the key of an object in a rbtree, this time it was the one for DSOs lookup by its long_name, and the noticed symptom was with 'perf buildid-list --with-hits' (Adrian Hunter) - 'perf inject' is a pipe, events it doesn't touch should be passed on, PERF_RECORD_LOST wasn't, fix it (Adrian Hunter) - Make 'perf buildid-list' request event ordering, as it needs to first get the mmap events to be able to mark wich DSOs had hits (Adrian Hunter) - Fix memory leaks on failure in 'perf probe' (Masami Hiramatsu, Wang Nan) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/perf/builtin-inject.c1
-rw-r--r--tools/perf/util/build-id.c1
-rw-r--r--tools/perf/util/dso.c17
-rw-r--r--tools/perf/util/dso.h1
-rw-r--r--tools/perf/util/machine.c1
-rw-r--r--tools/perf/util/probe-finder.c24
6 files changed, 38 insertions, 7 deletions
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 0a945d2e8ca5..99d127fe9c35 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -675,6 +675,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
675 .fork = perf_event__repipe, 675 .fork = perf_event__repipe,
676 .exit = perf_event__repipe, 676 .exit = perf_event__repipe,
677 .lost = perf_event__repipe, 677 .lost = perf_event__repipe,
678 .lost_samples = perf_event__repipe,
678 .aux = perf_event__repipe, 679 .aux = perf_event__repipe,
679 .itrace_start = perf_event__repipe, 680 .itrace_start = perf_event__repipe,
680 .context_switch = perf_event__repipe, 681 .context_switch = perf_event__repipe,
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index d909459fb54c..217b5a60e2ab 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -76,6 +76,7 @@ struct perf_tool build_id__mark_dso_hit_ops = {
76 .exit = perf_event__exit_del_thread, 76 .exit = perf_event__exit_del_thread,
77 .attr = perf_event__process_attr, 77 .attr = perf_event__process_attr,
78 .build_id = perf_event__process_build_id, 78 .build_id = perf_event__process_build_id,
79 .ordered_events = true,
79}; 80};
80 81
81int build_id__sprintf(const u8 *build_id, int len, char *bf) 82int build_id__sprintf(const u8 *build_id, int len, char *bf)
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 7c0c08386a1d..425df5c86c9c 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -933,6 +933,7 @@ static struct dso *__dso__findlink_by_longname(struct rb_root *root,
933 /* Add new node and rebalance tree */ 933 /* Add new node and rebalance tree */
934 rb_link_node(&dso->rb_node, parent, p); 934 rb_link_node(&dso->rb_node, parent, p);
935 rb_insert_color(&dso->rb_node, root); 935 rb_insert_color(&dso->rb_node, root);
936 dso->root = root;
936 } 937 }
937 return NULL; 938 return NULL;
938} 939}
@@ -945,15 +946,30 @@ static inline struct dso *__dso__find_by_longname(struct rb_root *root,
945 946
946void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated) 947void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
947{ 948{
949 struct rb_root *root = dso->root;
950
948 if (name == NULL) 951 if (name == NULL)
949 return; 952 return;
950 953
951 if (dso->long_name_allocated) 954 if (dso->long_name_allocated)
952 free((char *)dso->long_name); 955 free((char *)dso->long_name);
953 956
957 if (root) {
958 rb_erase(&dso->rb_node, root);
959 /*
960 * __dso__findlink_by_longname() isn't guaranteed to add it
961 * back, so a clean removal is required here.
962 */
963 RB_CLEAR_NODE(&dso->rb_node);
964 dso->root = NULL;
965 }
966
954 dso->long_name = name; 967 dso->long_name = name;
955 dso->long_name_len = strlen(name); 968 dso->long_name_len = strlen(name);
956 dso->long_name_allocated = name_allocated; 969 dso->long_name_allocated = name_allocated;
970
971 if (root)
972 __dso__findlink_by_longname(root, dso, NULL);
957} 973}
958 974
959void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated) 975void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
@@ -1046,6 +1062,7 @@ struct dso *dso__new(const char *name)
1046 dso->kernel = DSO_TYPE_USER; 1062 dso->kernel = DSO_TYPE_USER;
1047 dso->needs_swap = DSO_SWAP__UNSET; 1063 dso->needs_swap = DSO_SWAP__UNSET;
1048 RB_CLEAR_NODE(&dso->rb_node); 1064 RB_CLEAR_NODE(&dso->rb_node);
1065 dso->root = NULL;
1049 INIT_LIST_HEAD(&dso->node); 1066 INIT_LIST_HEAD(&dso->node);
1050 INIT_LIST_HEAD(&dso->data.open_entry); 1067 INIT_LIST_HEAD(&dso->data.open_entry);
1051 pthread_mutex_init(&dso->lock, NULL); 1068 pthread_mutex_init(&dso->lock, NULL);
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index fc8db9c764ac..45ec4d0a50ed 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -135,6 +135,7 @@ struct dso {
135 pthread_mutex_t lock; 135 pthread_mutex_t lock;
136 struct list_head node; 136 struct list_head node;
137 struct rb_node rb_node; /* rbtree node sorted by long name */ 137 struct rb_node rb_node; /* rbtree node sorted by long name */
138 struct rb_root *root; /* root of rbtree that rb_node is in */
138 struct rb_root symbols[MAP__NR_TYPES]; 139 struct rb_root symbols[MAP__NR_TYPES];
139 struct rb_root symbol_names[MAP__NR_TYPES]; 140 struct rb_root symbol_names[MAP__NR_TYPES];
140 struct { 141 struct {
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 5ef90be2a249..8b303ff20289 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -91,6 +91,7 @@ static void dsos__purge(struct dsos *dsos)
91 91
92 list_for_each_entry_safe(pos, n, &dsos->head, node) { 92 list_for_each_entry_safe(pos, n, &dsos->head, node) {
93 RB_CLEAR_NODE(&pos->rb_node); 93 RB_CLEAR_NODE(&pos->rb_node);
94 pos->root = NULL;
94 list_del_init(&pos->node); 95 list_del_init(&pos->node);
95 dso__put(pos); 96 dso__put(pos);
96 } 97 }
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index bd8f03de5e40..05012bb178d7 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1183,7 +1183,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1183 container_of(pf, struct trace_event_finder, pf); 1183 container_of(pf, struct trace_event_finder, pf);
1184 struct perf_probe_point *pp = &pf->pev->point; 1184 struct perf_probe_point *pp = &pf->pev->point;
1185 struct probe_trace_event *tev; 1185 struct probe_trace_event *tev;
1186 struct perf_probe_arg *args; 1186 struct perf_probe_arg *args = NULL;
1187 int ret, i; 1187 int ret, i;
1188 1188
1189 /* Check number of tevs */ 1189 /* Check number of tevs */
@@ -1198,19 +1198,23 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1198 ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr, 1198 ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
1199 pp->retprobe, pp->function, &tev->point); 1199 pp->retprobe, pp->function, &tev->point);
1200 if (ret < 0) 1200 if (ret < 0)
1201 return ret; 1201 goto end;
1202 1202
1203 tev->point.realname = strdup(dwarf_diename(sc_die)); 1203 tev->point.realname = strdup(dwarf_diename(sc_die));
1204 if (!tev->point.realname) 1204 if (!tev->point.realname) {
1205 return -ENOMEM; 1205 ret = -ENOMEM;
1206 goto end;
1207 }
1206 1208
1207 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, 1209 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
1208 tev->point.offset); 1210 tev->point.offset);
1209 1211
1210 /* Expand special probe argument if exist */ 1212 /* Expand special probe argument if exist */
1211 args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS); 1213 args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
1212 if (args == NULL) 1214 if (args == NULL) {
1213 return -ENOMEM; 1215 ret = -ENOMEM;
1216 goto end;
1217 }
1214 1218
1215 ret = expand_probe_args(sc_die, pf, args); 1219 ret = expand_probe_args(sc_die, pf, args);
1216 if (ret < 0) 1220 if (ret < 0)
@@ -1234,6 +1238,10 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1234 } 1238 }
1235 1239
1236end: 1240end:
1241 if (ret) {
1242 clear_probe_trace_event(tev);
1243 tf->ntevs--;
1244 }
1237 free(args); 1245 free(args);
1238 return ret; 1246 return ret;
1239} 1247}
@@ -1246,7 +1254,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
1246 struct trace_event_finder tf = { 1254 struct trace_event_finder tf = {
1247 .pf = {.pev = pev, .callback = add_probe_trace_event}, 1255 .pf = {.pev = pev, .callback = add_probe_trace_event},
1248 .max_tevs = probe_conf.max_probes, .mod = dbg->mod}; 1256 .max_tevs = probe_conf.max_probes, .mod = dbg->mod};
1249 int ret; 1257 int ret, i;
1250 1258
1251 /* Allocate result tevs array */ 1259 /* Allocate result tevs array */
1252 *tevs = zalloc(sizeof(struct probe_trace_event) * tf.max_tevs); 1260 *tevs = zalloc(sizeof(struct probe_trace_event) * tf.max_tevs);
@@ -1258,6 +1266,8 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
1258 1266
1259 ret = debuginfo__find_probes(dbg, &tf.pf); 1267 ret = debuginfo__find_probes(dbg, &tf.pf);
1260 if (ret < 0) { 1268 if (ret < 0) {
1269 for (i = 0; i < tf.ntevs; i++)
1270 clear_probe_trace_event(&tf.tevs[i]);
1261 zfree(tevs); 1271 zfree(tevs);
1262 return ret; 1272 return ret;
1263 } 1273 }