Skip to content

Commit e15bf88

Browse files
author
Ingo Molnar
committed
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 <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
2 parents 2a49f02 + 092b1f0 commit e15bf88

File tree

6 files changed

+38
-7
lines changed

6 files changed

+38
-7
lines changed

tools/perf/builtin-inject.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
675675
.fork = perf_event__repipe,
676676
.exit = perf_event__repipe,
677677
.lost = perf_event__repipe,
678+
.lost_samples = perf_event__repipe,
678679
.aux = perf_event__repipe,
679680
.itrace_start = perf_event__repipe,
680681
.context_switch = perf_event__repipe,

tools/perf/util/build-id.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ struct perf_tool build_id__mark_dso_hit_ops = {
7676
.exit = perf_event__exit_del_thread,
7777
.attr = perf_event__process_attr,
7878
.build_id = perf_event__process_build_id,
79+
.ordered_events = true,
7980
};
8081

8182
int build_id__sprintf(const u8 *build_id, int len, char *bf)

tools/perf/util/dso.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ static struct dso *__dso__findlink_by_longname(struct rb_root *root,
933933
/* Add new node and rebalance tree */
934934
rb_link_node(&dso->rb_node, parent, p);
935935
rb_insert_color(&dso->rb_node, root);
936+
dso->root = root;
936937
}
937938
return NULL;
938939
}
@@ -945,15 +946,30 @@ static inline struct dso *__dso__find_by_longname(struct rb_root *root,
945946

946947
void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
947948
{
949+
struct rb_root *root = dso->root;
950+
948951
if (name == NULL)
949952
return;
950953

951954
if (dso->long_name_allocated)
952955
free((char *)dso->long_name);
953956

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+
954967
dso->long_name = name;
955968
dso->long_name_len = strlen(name);
956969
dso->long_name_allocated = name_allocated;
970+
971+
if (root)
972+
__dso__findlink_by_longname(root, dso, NULL);
957973
}
958974

959975
void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
@@ -1046,6 +1062,7 @@ struct dso *dso__new(const char *name)
10461062
dso->kernel = DSO_TYPE_USER;
10471063
dso->needs_swap = DSO_SWAP__UNSET;
10481064
RB_CLEAR_NODE(&dso->rb_node);
1065+
dso->root = NULL;
10491066
INIT_LIST_HEAD(&dso->node);
10501067
INIT_LIST_HEAD(&dso->data.open_entry);
10511068
pthread_mutex_init(&dso->lock, NULL);

tools/perf/util/dso.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ struct dso {
135135
pthread_mutex_t lock;
136136
struct list_head node;
137137
struct rb_node rb_node; /* rbtree node sorted by long name */
138+
struct rb_root *root; /* root of rbtree that rb_node is in */
138139
struct rb_root symbols[MAP__NR_TYPES];
139140
struct rb_root symbol_names[MAP__NR_TYPES];
140141
struct {

tools/perf/util/machine.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ static void dsos__purge(struct dsos *dsos)
9191

9292
list_for_each_entry_safe(pos, n, &dsos->head, node) {
9393
RB_CLEAR_NODE(&pos->rb_node);
94+
pos->root = NULL;
9495
list_del_init(&pos->node);
9596
dso__put(pos);
9697
}

tools/perf/util/probe-finder.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
11831183
container_of(pf, struct trace_event_finder, pf);
11841184
struct perf_probe_point *pp = &pf->pev->point;
11851185
struct probe_trace_event *tev;
1186-
struct perf_probe_arg *args;
1186+
struct perf_probe_arg *args = NULL;
11871187
int ret, i;
11881188

11891189
/* Check number of tevs */
@@ -1198,19 +1198,23 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
11981198
ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
11991199
pp->retprobe, pp->function, &tev->point);
12001200
if (ret < 0)
1201-
return ret;
1201+
goto end;
12021202

12031203
tev->point.realname = strdup(dwarf_diename(sc_die));
1204-
if (!tev->point.realname)
1205-
return -ENOMEM;
1204+
if (!tev->point.realname) {
1205+
ret = -ENOMEM;
1206+
goto end;
1207+
}
12061208

12071209
pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
12081210
tev->point.offset);
12091211

12101212
/* Expand special probe argument if exist */
12111213
args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
1212-
if (args == NULL)
1213-
return -ENOMEM;
1214+
if (args == NULL) {
1215+
ret = -ENOMEM;
1216+
goto end;
1217+
}
12141218

12151219
ret = expand_probe_args(sc_die, pf, args);
12161220
if (ret < 0)
@@ -1234,6 +1238,10 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
12341238
}
12351239

12361240
end:
1241+
if (ret) {
1242+
clear_probe_trace_event(tev);
1243+
tf->ntevs--;
1244+
}
12371245
free(args);
12381246
return ret;
12391247
}
@@ -1246,7 +1254,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
12461254
struct trace_event_finder tf = {
12471255
.pf = {.pev = pev, .callback = add_probe_trace_event},
12481256
.max_tevs = probe_conf.max_probes, .mod = dbg->mod};
1249-
int ret;
1257+
int ret, i;
12501258

12511259
/* Allocate result tevs array */
12521260
*tevs = zalloc(sizeof(struct probe_trace_event) * tf.max_tevs);
@@ -1258,6 +1266,8 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
12581266

12591267
ret = debuginfo__find_probes(dbg, &tf.pf);
12601268
if (ret < 0) {
1269+
for (i = 0; i < tf.ntevs; i++)
1270+
clear_probe_trace_event(&tf.tevs[i]);
12611271
zfree(tevs);
12621272
return ret;
12631273
}

0 commit comments

Comments
 (0)