perf/urgent fixes:
- 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> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWRk2HAAoJENZQFvNTUqpAxFwQAIFwg/Gxn+CUgX1mhc9XlvpR pUGt0AqzF/RLG3eiq+3BzL6+q2Lm57AsNqmp2nbrfl+5/zH60zqGsgjjD+Uz19rP nfIIaxtjEwwxaF6FmYKRrw73IABSQSEozDaaNh/rV1CKc4y9PQ9BchTDyl8hKGg9 ARZKw2lteI73t5m0ie2vIAiuYpTSlOohGLTtWMGfaRImsZJlSCJ8mWyrFhWwvrNS TvVpHODCWmeWa8JdPSo0waF0y6wo3Fdy7OYGHa56kKc6fa5HuQrH6b+L7BwETX+4 7T/medMCVy1erCNStnOui3JSRLpZmiDfp0uw19uyQTTF8tgmLjRQsEyLV5njiA7a x6we2leArLGmGKR4+mm0NnjBU+2I8CaOcqfwlWeZOUl7wFMMIPkrqvebIAOa1Cbf dQoi2suIwPHN+7KMu7XceIy75yMq8qsljMoC/7Rjny/AQsx5rXheHYBtzMFskwyy a8abmslTMmwWhZfQy3J6xR/lTIXHqPwa5inT+RDJfa8hPcECEV1NWNrBKJNCW1zV v6tA+LkjyR6O7wPrpaW12nb0PcKFq6numOSc0/rDXQJjqtX/XxbsnbY8mm410tzy qjE8rmImr1rKDRuS6tFdktHLTQOmJVUSIXoBFmyYX7Vb2XxqvScQth4SjQpoe1WA imlPrBpfNP6CLuOqMnSD =wIL5 -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
e15bf88a44
|
@ -675,6 +675,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
.fork = perf_event__repipe,
|
.fork = perf_event__repipe,
|
||||||
.exit = perf_event__repipe,
|
.exit = perf_event__repipe,
|
||||||
.lost = perf_event__repipe,
|
.lost = perf_event__repipe,
|
||||||
|
.lost_samples = perf_event__repipe,
|
||||||
.aux = perf_event__repipe,
|
.aux = perf_event__repipe,
|
||||||
.itrace_start = perf_event__repipe,
|
.itrace_start = perf_event__repipe,
|
||||||
.context_switch = perf_event__repipe,
|
.context_switch = perf_event__repipe,
|
||||||
|
|
|
@ -76,6 +76,7 @@ struct perf_tool build_id__mark_dso_hit_ops = {
|
||||||
.exit = perf_event__exit_del_thread,
|
.exit = perf_event__exit_del_thread,
|
||||||
.attr = perf_event__process_attr,
|
.attr = perf_event__process_attr,
|
||||||
.build_id = perf_event__process_build_id,
|
.build_id = perf_event__process_build_id,
|
||||||
|
.ordered_events = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
int build_id__sprintf(const u8 *build_id, int len, char *bf)
|
int build_id__sprintf(const u8 *build_id, int len, char *bf)
|
||||||
|
|
|
@ -933,6 +933,7 @@ static struct dso *__dso__findlink_by_longname(struct rb_root *root,
|
||||||
/* Add new node and rebalance tree */
|
/* Add new node and rebalance tree */
|
||||||
rb_link_node(&dso->rb_node, parent, p);
|
rb_link_node(&dso->rb_node, parent, p);
|
||||||
rb_insert_color(&dso->rb_node, root);
|
rb_insert_color(&dso->rb_node, root);
|
||||||
|
dso->root = root;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -945,15 +946,30 @@ static inline struct dso *__dso__find_by_longname(struct rb_root *root,
|
||||||
|
|
||||||
void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
|
void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
|
||||||
{
|
{
|
||||||
|
struct rb_root *root = dso->root;
|
||||||
|
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dso->long_name_allocated)
|
if (dso->long_name_allocated)
|
||||||
free((char *)dso->long_name);
|
free((char *)dso->long_name);
|
||||||
|
|
||||||
|
if (root) {
|
||||||
|
rb_erase(&dso->rb_node, root);
|
||||||
|
/*
|
||||||
|
* __dso__findlink_by_longname() isn't guaranteed to add it
|
||||||
|
* back, so a clean removal is required here.
|
||||||
|
*/
|
||||||
|
RB_CLEAR_NODE(&dso->rb_node);
|
||||||
|
dso->root = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
dso->long_name = name;
|
dso->long_name = name;
|
||||||
dso->long_name_len = strlen(name);
|
dso->long_name_len = strlen(name);
|
||||||
dso->long_name_allocated = name_allocated;
|
dso->long_name_allocated = name_allocated;
|
||||||
|
|
||||||
|
if (root)
|
||||||
|
__dso__findlink_by_longname(root, dso, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
|
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)
|
||||||
dso->kernel = DSO_TYPE_USER;
|
dso->kernel = DSO_TYPE_USER;
|
||||||
dso->needs_swap = DSO_SWAP__UNSET;
|
dso->needs_swap = DSO_SWAP__UNSET;
|
||||||
RB_CLEAR_NODE(&dso->rb_node);
|
RB_CLEAR_NODE(&dso->rb_node);
|
||||||
|
dso->root = NULL;
|
||||||
INIT_LIST_HEAD(&dso->node);
|
INIT_LIST_HEAD(&dso->node);
|
||||||
INIT_LIST_HEAD(&dso->data.open_entry);
|
INIT_LIST_HEAD(&dso->data.open_entry);
|
||||||
pthread_mutex_init(&dso->lock, NULL);
|
pthread_mutex_init(&dso->lock, NULL);
|
||||||
|
|
|
@ -135,6 +135,7 @@ struct dso {
|
||||||
pthread_mutex_t lock;
|
pthread_mutex_t lock;
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
struct rb_node rb_node; /* rbtree node sorted by long name */
|
struct rb_node rb_node; /* rbtree node sorted by long name */
|
||||||
|
struct rb_root *root; /* root of rbtree that rb_node is in */
|
||||||
struct rb_root symbols[MAP__NR_TYPES];
|
struct rb_root symbols[MAP__NR_TYPES];
|
||||||
struct rb_root symbol_names[MAP__NR_TYPES];
|
struct rb_root symbol_names[MAP__NR_TYPES];
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -91,6 +91,7 @@ static void dsos__purge(struct dsos *dsos)
|
||||||
|
|
||||||
list_for_each_entry_safe(pos, n, &dsos->head, node) {
|
list_for_each_entry_safe(pos, n, &dsos->head, node) {
|
||||||
RB_CLEAR_NODE(&pos->rb_node);
|
RB_CLEAR_NODE(&pos->rb_node);
|
||||||
|
pos->root = NULL;
|
||||||
list_del_init(&pos->node);
|
list_del_init(&pos->node);
|
||||||
dso__put(pos);
|
dso__put(pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1183,7 +1183,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
|
||||||
container_of(pf, struct trace_event_finder, pf);
|
container_of(pf, struct trace_event_finder, pf);
|
||||||
struct perf_probe_point *pp = &pf->pev->point;
|
struct perf_probe_point *pp = &pf->pev->point;
|
||||||
struct probe_trace_event *tev;
|
struct probe_trace_event *tev;
|
||||||
struct perf_probe_arg *args;
|
struct perf_probe_arg *args = NULL;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
/* Check number of tevs */
|
/* Check number of tevs */
|
||||||
|
@ -1198,19 +1198,23 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
|
||||||
ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
|
ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
|
||||||
pp->retprobe, pp->function, &tev->point);
|
pp->retprobe, pp->function, &tev->point);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto end;
|
||||||
|
|
||||||
tev->point.realname = strdup(dwarf_diename(sc_die));
|
tev->point.realname = strdup(dwarf_diename(sc_die));
|
||||||
if (!tev->point.realname)
|
if (!tev->point.realname) {
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
|
pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
|
||||||
tev->point.offset);
|
tev->point.offset);
|
||||||
|
|
||||||
/* Expand special probe argument if exist */
|
/* Expand special probe argument if exist */
|
||||||
args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
|
args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
|
||||||
if (args == NULL)
|
if (args == NULL) {
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
ret = expand_probe_args(sc_die, pf, args);
|
ret = expand_probe_args(sc_die, pf, args);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -1234,6 +1238,10 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
if (ret) {
|
||||||
|
clear_probe_trace_event(tev);
|
||||||
|
tf->ntevs--;
|
||||||
|
}
|
||||||
free(args);
|
free(args);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1246,7 +1254,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
|
||||||
struct trace_event_finder tf = {
|
struct trace_event_finder tf = {
|
||||||
.pf = {.pev = pev, .callback = add_probe_trace_event},
|
.pf = {.pev = pev, .callback = add_probe_trace_event},
|
||||||
.max_tevs = probe_conf.max_probes, .mod = dbg->mod};
|
.max_tevs = probe_conf.max_probes, .mod = dbg->mod};
|
||||||
int ret;
|
int ret, i;
|
||||||
|
|
||||||
/* Allocate result tevs array */
|
/* Allocate result tevs array */
|
||||||
*tevs = zalloc(sizeof(struct probe_trace_event) * tf.max_tevs);
|
*tevs = zalloc(sizeof(struct probe_trace_event) * tf.max_tevs);
|
||||||
|
@ -1258,6 +1266,8 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
|
||||||
|
|
||||||
ret = debuginfo__find_probes(dbg, &tf.pf);
|
ret = debuginfo__find_probes(dbg, &tf.pf);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
for (i = 0; i < tf.ntevs; i++)
|
||||||
|
clear_probe_trace_event(&tf.tevs[i]);
|
||||||
zfree(tevs);
|
zfree(tevs);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue