forked from Minki/linux
perf/core improvements and fixes:
New features: - Add 'callindent' option to 'perf script -F', to indent the Intel PT call stack, making this output more ftrace-like (Adrian Hunter, Andi Kleen) User visible: - Enlarge 'pid' column width, to cope with large pids (Jiri Olsa) Infrastructure: - Cross platform unwind fixes (He Kuang) - Make destructors accept NULL, behaving like free() (Arnaldo Carvalho de Melo) - Remove reference to perl interpreted in the recently added 'perf script' stackcollapse python script (Arnaldo Carvalho de Melo) - Rename CLASS__for_each() macros to CLASS__for_each_entry(), to use the list_for_each_entry() semantics, as most of these class specific loop helpers are list_for_each_entry*() wrappers (Arnaldo Carvalho de Melo) - Expose the hist_browser code, will be used with data structures other than perf_evsel (Jiri Olsa) - 'perf config' refactorings (Taeung Song) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJXbFIcAAoJENZQFvNTUqpADw0QAJzIZK63uJ+kA3eq91go3oJi GDYqhA/HSV6cBHKG4CEuemKLYIK6GrnmLYK8wPquh8h1VkoRmBuV7AoLUbUdVW6P uINnJXqC45d/picN6z4K/KLfZAt/cT3FEl/JIRcMw72SyNhHfOvcPEUWZ+FCikWR 11FtuU4bjIc+ctiXxn+Gwx1v3NacATRDIBiqHaUPVZtbWLXOcWKvgX6F6a0WCDF9 0SPSyoW6nZDEl4aZScQ4eW8XwF4xFZesj0q/8JOP0XrMGQ7HtcvRSSoXhTrTlE5f MGF6OIfNOBuQhqKDrpfU/jwCqORA4dcv67iTo2MCfq+w3FiLMMCU7pB9543N5YT6 WW70k2/AvFnhuD5gRZMHGZujRw7Ya1ZnVt9V6WtT5ia4he7dJC/7g26nee1OLRrT ug0l/03xOVVsZYQrAFo3efMYS7uMqMUP1Sdp5ujZ/KoEuSsQ/PJSvGyInsB9k994 nmz4jGhDdRV7AqrxnhIwmcQJmukWSPjYF3Ei3rHRxa18HC29rKPQ9GvJHMMKt7wT JRP/Mle3ZyzRnMjFP+Rc/MOzQruqatCy3d/NH7ndL/UFzlW+873USK8Uj9VxuX20 fvgl4yVcHJIzjiguuzF2AADpweWUdyk0oKMcyXblGT3Iokmr3su15Ml/Lg/U4sVN ey2y0qcut8K1uV1++Wlq =HRRs -----END PGP SIGNATURE----- Merge tag 'perf-core-for-mingo-20160623' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: New features: - Add 'callindent' option to 'perf script -F', to indent the Intel PT call stack, making this output more ftrace-like (Adrian Hunter, Andi Kleen) User visible changes: - Enlarge 'pid' column width, to cope with large pids (Jiri Olsa) Infrastructure changes: - Fix cross platform unwind (He Kuang) - Make destructors accept NULL, behaving like free() (Arnaldo Carvalho de Melo) - Remove reference to perl interpreted in the recently added 'perf script' stackcollapse python script (Arnaldo Carvalho de Melo) - Rename CLASS__for_each() macros to CLASS__for_each_entry(), to use the list_for_each_entry() semantics, as most of these class specific loop helpers are list_for_each_entry*() wrappers (Arnaldo Carvalho de Melo) - Expose the hist_browser code, will be used with data structures other than perf_evsel (Jiri Olsa) - Refactor 'perf config' (Taeung Song) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
9840b1ae45
@ -170,7 +170,16 @@ OPTIONS
|
||||
Trace decoding. The flags are "bcrosyiABEx" which stand for branch,
|
||||
call, return, conditional, system, asynchronous, interrupt,
|
||||
transaction abort, trace begin, trace end, and in transaction,
|
||||
respectively.
|
||||
respectively. Known combinations of flags are printed more nicely e.g.
|
||||
"call" for "bc", "return" for "br", "jcc" for "bo", "jmp" for "b",
|
||||
"int" for "bci", "iret" for "bri", "syscall" for "bcs", "sysret" for "brs",
|
||||
"async" for "by", "hw int" for "bcyi", "tx abrt" for "bA", "tr strt" for "bB",
|
||||
"tr end" for "bE". However the "x" flag will be display separately in those
|
||||
cases e.g. "jcc (x)" for a condition branch within a transaction.
|
||||
|
||||
The callindent field is synthesized and may have a value when
|
||||
Instruction Trace decoding. For calls and returns, it will display the
|
||||
name of the symbol indented with spaces to reflect the stack depth.
|
||||
|
||||
Finally, a user may not set fields to none for all event types.
|
||||
i.e., -F "" is not allowed.
|
||||
|
@ -254,7 +254,8 @@ PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
|
||||
PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPI)
|
||||
|
||||
$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST)
|
||||
$(QUIET_GEN)CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \
|
||||
$(QUIET_GEN)LDSHARED="$(CC) -pthread -shared" \
|
||||
CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \
|
||||
$(PYTHON_WORD) util/setup.py \
|
||||
--quiet build_ext; \
|
||||
mkdir -p $(OUTPUT)python && \
|
||||
|
@ -154,10 +154,6 @@ next_event:
|
||||
err = 0;
|
||||
|
||||
out_err:
|
||||
if (evlist) {
|
||||
perf_evlist__disable(evlist);
|
||||
perf_evlist__delete(evlist);
|
||||
}
|
||||
|
||||
perf_evlist__delete(evlist);
|
||||
return err;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ struct auxtrace_record *auxtrace_record__init_intel(struct perf_evlist *evlist,
|
||||
intel_bts_pmu = perf_pmu__find(INTEL_BTS_PMU_NAME);
|
||||
|
||||
if (evlist) {
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (intel_pt_pmu &&
|
||||
evsel->attr.type == intel_pt_pmu->type)
|
||||
found_pt = true;
|
||||
|
@ -124,7 +124,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr,
|
||||
btsr->evlist = evlist;
|
||||
btsr->snapshot_mode = opts->auxtrace_snapshot_mode;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.type == intel_bts_pmu->type) {
|
||||
if (intel_bts_evsel) {
|
||||
pr_err("There may be only one " INTEL_BTS_PMU_NAME " event\n");
|
||||
@ -327,7 +327,7 @@ static int intel_bts_snapshot_start(struct auxtrace_record *itr)
|
||||
container_of(itr, struct intel_bts_recording, itr);
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(btsr->evlist, evsel) {
|
||||
evlist__for_each_entry(btsr->evlist, evsel) {
|
||||
if (evsel->attr.type == btsr->intel_bts_pmu->type)
|
||||
return perf_evsel__disable(evsel);
|
||||
}
|
||||
@ -340,7 +340,7 @@ static int intel_bts_snapshot_finish(struct auxtrace_record *itr)
|
||||
container_of(itr, struct intel_bts_recording, itr);
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(btsr->evlist, evsel) {
|
||||
evlist__for_each_entry(btsr->evlist, evsel) {
|
||||
if (evsel->attr.type == btsr->intel_bts_pmu->type)
|
||||
return perf_evsel__enable(evsel);
|
||||
}
|
||||
@ -422,7 +422,7 @@ static int intel_bts_read_finish(struct auxtrace_record *itr, int idx)
|
||||
container_of(itr, struct intel_bts_recording, itr);
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(btsr->evlist, evsel) {
|
||||
evlist__for_each_entry(btsr->evlist, evsel) {
|
||||
if (evsel->attr.type == btsr->intel_bts_pmu->type)
|
||||
return perf_evlist__enable_event_idx(btsr->evlist,
|
||||
evsel, idx);
|
||||
|
@ -131,7 +131,7 @@ static int intel_pt_read_config(struct perf_pmu *intel_pt_pmu, const char *str,
|
||||
if (!mask)
|
||||
return -EINVAL;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.type == intel_pt_pmu->type) {
|
||||
*res = intel_pt_masked_bits(mask, evsel->attr.config);
|
||||
return 0;
|
||||
@ -511,7 +511,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
|
||||
ptr->evlist = evlist;
|
||||
ptr->snapshot_mode = opts->auxtrace_snapshot_mode;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.type == intel_pt_pmu->type) {
|
||||
if (intel_pt_evsel) {
|
||||
pr_err("There may be only one " INTEL_PT_PMU_NAME " event\n");
|
||||
@ -725,7 +725,7 @@ static int intel_pt_snapshot_start(struct auxtrace_record *itr)
|
||||
container_of(itr, struct intel_pt_recording, itr);
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(ptr->evlist, evsel) {
|
||||
evlist__for_each_entry(ptr->evlist, evsel) {
|
||||
if (evsel->attr.type == ptr->intel_pt_pmu->type)
|
||||
return perf_evsel__disable(evsel);
|
||||
}
|
||||
@ -738,7 +738,7 @@ static int intel_pt_snapshot_finish(struct auxtrace_record *itr)
|
||||
container_of(itr, struct intel_pt_recording, itr);
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(ptr->evlist, evsel) {
|
||||
evlist__for_each_entry(ptr->evlist, evsel) {
|
||||
if (evsel->attr.type == ptr->intel_pt_pmu->type)
|
||||
return perf_evsel__enable(evsel);
|
||||
}
|
||||
@ -1011,7 +1011,7 @@ static int intel_pt_read_finish(struct auxtrace_record *itr, int idx)
|
||||
container_of(itr, struct intel_pt_recording, itr);
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(ptr->evlist, evsel) {
|
||||
evlist__for_each_entry(ptr->evlist, evsel) {
|
||||
if (evsel->attr.type == ptr->intel_pt_pmu->type)
|
||||
return perf_evlist__enable_event_idx(ptr->evlist, evsel,
|
||||
idx);
|
||||
|
@ -236,7 +236,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
|
||||
perf_session__fprintf_dsos(session, stdout);
|
||||
|
||||
total_nr_samples = 0;
|
||||
evlist__for_each(session->evlist, pos) {
|
||||
evlist__for_each_entry(session->evlist, pos) {
|
||||
struct hists *hists = evsel__hists(pos);
|
||||
u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
|
||||
|
||||
|
@ -209,7 +209,7 @@ static int build_id_cache__purge_path(const char *pathname)
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
strlist__for_each(pos, list) {
|
||||
strlist__for_each_entry(pos, list) {
|
||||
err = build_id_cache__remove_s(pos->s);
|
||||
pr_debug("Removing %s %s: %s\n", pos->s, pathname,
|
||||
err ? "FAIL" : "Ok");
|
||||
@ -343,7 +343,7 @@ int cmd_buildid_cache(int argc, const char **argv,
|
||||
if (add_name_list_str) {
|
||||
list = strlist__new(add_name_list_str, NULL);
|
||||
if (list) {
|
||||
strlist__for_each(pos, list)
|
||||
strlist__for_each_entry(pos, list)
|
||||
if (build_id_cache__add_file(pos->s)) {
|
||||
if (errno == EEXIST) {
|
||||
pr_debug("%s already in the cache\n",
|
||||
@ -361,7 +361,7 @@ int cmd_buildid_cache(int argc, const char **argv,
|
||||
if (remove_name_list_str) {
|
||||
list = strlist__new(remove_name_list_str, NULL);
|
||||
if (list) {
|
||||
strlist__for_each(pos, list)
|
||||
strlist__for_each_entry(pos, list)
|
||||
if (build_id_cache__remove_file(pos->s)) {
|
||||
if (errno == ENOENT) {
|
||||
pr_debug("%s wasn't in the cache\n",
|
||||
@ -379,7 +379,7 @@ int cmd_buildid_cache(int argc, const char **argv,
|
||||
if (purge_name_list_str) {
|
||||
list = strlist__new(purge_name_list_str, NULL);
|
||||
if (list) {
|
||||
strlist__for_each(pos, list)
|
||||
strlist__for_each_entry(pos, list)
|
||||
if (build_id_cache__purge_path(pos->s)) {
|
||||
if (errno == ENOENT) {
|
||||
pr_debug("%s wasn't in the cache\n",
|
||||
@ -400,7 +400,7 @@ int cmd_buildid_cache(int argc, const char **argv,
|
||||
if (update_name_list_str) {
|
||||
list = strlist__new(update_name_list_str, NULL);
|
||||
if (list) {
|
||||
strlist__for_each(pos, list)
|
||||
strlist__for_each_entry(pos, list)
|
||||
if (build_id_cache__update_file(pos->s)) {
|
||||
if (errno == ENOENT) {
|
||||
pr_debug("%s wasn't in the cache\n",
|
||||
@ -419,8 +419,7 @@ int cmd_buildid_cache(int argc, const char **argv,
|
||||
pr_warning("Couldn't add %s\n", kcore_filename);
|
||||
|
||||
out:
|
||||
if (session)
|
||||
perf_session__delete(session);
|
||||
perf_session__delete(session);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -37,23 +37,16 @@ static int show_config(struct perf_config_set *set)
|
||||
{
|
||||
struct perf_config_section *section;
|
||||
struct perf_config_item *item;
|
||||
struct list_head *sections;
|
||||
|
||||
if (set == NULL)
|
||||
return -1;
|
||||
|
||||
sections = &set->sections;
|
||||
if (list_empty(sections))
|
||||
return -1;
|
||||
perf_config_set__for_each_entry(set, section, item) {
|
||||
char *value = item->value;
|
||||
|
||||
list_for_each_entry(section, sections, node) {
|
||||
list_for_each_entry(item, §ion->items, node) {
|
||||
char *value = item->value;
|
||||
|
||||
if (value)
|
||||
printf("%s.%s=%s\n", section->name,
|
||||
item->name, value);
|
||||
}
|
||||
if (value)
|
||||
printf("%s.%s=%s\n", section->name,
|
||||
item->name, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -80,6 +73,10 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
else if (use_user_config)
|
||||
config_exclusive_filename = user_config;
|
||||
|
||||
/*
|
||||
* At only 'config' sub-command, individually use the config set
|
||||
* because of reinitializing with options config file location.
|
||||
*/
|
||||
set = perf_config_set__new();
|
||||
if (!set) {
|
||||
ret = -1;
|
||||
|
@ -363,7 +363,7 @@ static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
|
||||
{
|
||||
struct perf_evsel *e;
|
||||
|
||||
evlist__for_each(evlist, e) {
|
||||
evlist__for_each_entry(evlist, e) {
|
||||
if (perf_evsel__match2(evsel, e))
|
||||
return e;
|
||||
}
|
||||
@ -375,7 +375,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
struct hists *hists = evsel__hists(evsel);
|
||||
|
||||
hists__collapse_resort(hists, NULL);
|
||||
@ -681,7 +681,7 @@ static void data_process(void)
|
||||
struct perf_evsel *evsel_base;
|
||||
bool first = true;
|
||||
|
||||
evlist__for_each(evlist_base, evsel_base) {
|
||||
evlist__for_each_entry(evlist_base, evsel_base) {
|
||||
struct hists *hists_base = evsel__hists(evsel_base);
|
||||
struct data__file *d;
|
||||
int i;
|
||||
@ -756,9 +756,7 @@ static int __cmd_diff(void)
|
||||
|
||||
out_delete:
|
||||
data__for_each_file(i, d) {
|
||||
if (d->session)
|
||||
perf_session__delete(d->session);
|
||||
|
||||
perf_session__delete(d->session);
|
||||
data__free(d);
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
|
||||
evlist__for_each(session->evlist, pos) {
|
||||
evlist__for_each_entry(session->evlist, pos) {
|
||||
perf_evsel__fprintf(pos, details, stdout);
|
||||
|
||||
if (pos->attr.type == PERF_TYPE_TRACEPOINT)
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Builtin help command
|
||||
*/
|
||||
#include "perf.h"
|
||||
#include "util/cache.h"
|
||||
#include "util/config.h"
|
||||
#include "builtin.h"
|
||||
#include <subcmd/exec-cmd.h>
|
||||
#include "common-cmds.h"
|
||||
|
@ -562,7 +562,7 @@ static void strip_init(struct perf_inject *inject)
|
||||
|
||||
inject->tool.context_switch = perf_event__drop;
|
||||
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
evsel->handler = drop_sample;
|
||||
}
|
||||
|
||||
@ -590,7 +590,7 @@ static bool ok_to_remove(struct perf_evlist *evlist,
|
||||
if (!has_tracking(evsel_to_remove))
|
||||
return true;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->handler != drop_sample) {
|
||||
cnt += 1;
|
||||
if ((evsel->attr.sample_type & COMPAT_MASK) ==
|
||||
@ -608,7 +608,7 @@ static void strip_fini(struct perf_inject *inject)
|
||||
struct perf_evsel *evsel, *tmp;
|
||||
|
||||
/* Remove non-synthesized evsels if possible */
|
||||
evlist__for_each_safe(evlist, tmp, evsel) {
|
||||
evlist__for_each_entry_safe(evlist, tmp, evsel) {
|
||||
if (evsel->handler == drop_sample &&
|
||||
ok_to_remove(evlist, evsel)) {
|
||||
pr_debug("Deleting %s\n", perf_evsel__name(evsel));
|
||||
@ -643,7 +643,7 @@ static int __cmd_inject(struct perf_inject *inject)
|
||||
} else if (inject->sched_stat) {
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
const char *name = perf_evsel__name(evsel);
|
||||
|
||||
if (!strcmp(name, "sched:sched_switch")) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "util/evlist.h"
|
||||
#include "util/evsel.h"
|
||||
#include "util/util.h"
|
||||
#include "util/cache.h"
|
||||
#include "util/config.h"
|
||||
#include "util/symbol.h"
|
||||
#include "util/thread.h"
|
||||
#include "util/header.h"
|
||||
@ -1354,7 +1354,7 @@ static int __cmd_kmem(struct perf_session *session)
|
||||
goto out;
|
||||
}
|
||||
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (!strcmp(perf_evsel__name(evsel), "kmem:mm_page_alloc") &&
|
||||
perf_evsel__field(evsel, "pfn")) {
|
||||
use_pfn = true;
|
||||
|
@ -988,7 +988,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
|
||||
* Note: exclude_{guest,host} do not apply here.
|
||||
* This command processes KVM tracepoints from host only
|
||||
*/
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
struct perf_event_attr *attr = &pos->attr;
|
||||
|
||||
/* make sure these *are* set */
|
||||
@ -1426,11 +1426,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
|
||||
err = kvm_events_live_report(kvm);
|
||||
|
||||
out:
|
||||
if (kvm->session)
|
||||
perf_session__delete(kvm->session);
|
||||
perf_session__delete(kvm->session);
|
||||
kvm->session = NULL;
|
||||
if (kvm->evlist)
|
||||
perf_evlist__delete(kvm->evlist);
|
||||
perf_evlist__delete(kvm->evlist);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -389,7 +389,7 @@ static int perf_del_probe_events(struct strfilter *filter)
|
||||
|
||||
ret = probe_file__get_events(kfd, filter, klist);
|
||||
if (ret == 0) {
|
||||
strlist__for_each(ent, klist)
|
||||
strlist__for_each_entry(ent, klist)
|
||||
pr_info("Removed event: %s\n", ent->s);
|
||||
|
||||
ret = probe_file__del_strlist(kfd, klist);
|
||||
@ -399,7 +399,7 @@ static int perf_del_probe_events(struct strfilter *filter)
|
||||
|
||||
ret2 = probe_file__get_events(ufd, filter, ulist);
|
||||
if (ret2 == 0) {
|
||||
strlist__for_each(ent, ulist)
|
||||
strlist__for_each_entry(ent, ulist)
|
||||
pr_info("Removed event: %s\n", ent->s);
|
||||
|
||||
ret2 = probe_file__del_strlist(ufd, ulist);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "util/util.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
#include "util/parse-events.h"
|
||||
#include "util/config.h"
|
||||
|
||||
#include "util/callchain.h"
|
||||
#include "util/cgroup.h"
|
||||
@ -352,7 +353,7 @@ static int record__open(struct record *rec)
|
||||
|
||||
perf_evlist__config(evlist, opts, &callchain_param);
|
||||
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
try_again:
|
||||
if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
|
||||
if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "builtin.h"
|
||||
|
||||
#include "util/util.h"
|
||||
#include "util/cache.h"
|
||||
#include "util/config.h"
|
||||
|
||||
#include "util/annotate.h"
|
||||
#include "util/color.h"
|
||||
@ -361,7 +361,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
|
||||
struct perf_evsel *pos;
|
||||
|
||||
fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n", evlist->stats.total_lost_samples);
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
struct hists *hists = evsel__hists(pos);
|
||||
const char *evname = perf_evsel__name(pos);
|
||||
|
||||
@ -478,7 +478,7 @@ static int report__collapse_hists(struct report *rep)
|
||||
|
||||
ui_progress__init(&prog, rep->nr_entries, "Merging related events...");
|
||||
|
||||
evlist__for_each(rep->session->evlist, pos) {
|
||||
evlist__for_each_entry(rep->session->evlist, pos) {
|
||||
struct hists *hists = evsel__hists(pos);
|
||||
|
||||
if (pos->idx == 0)
|
||||
@ -511,7 +511,7 @@ static void report__output_resort(struct report *rep)
|
||||
|
||||
ui_progress__init(&prog, rep->nr_entries, "Sorting events for output...");
|
||||
|
||||
evlist__for_each(rep->session->evlist, pos)
|
||||
evlist__for_each_entry(rep->session->evlist, pos)
|
||||
perf_evsel__output_resort(pos, &prog);
|
||||
|
||||
ui_progress__finish();
|
||||
@ -552,7 +552,7 @@ static int __cmd_report(struct report *rep)
|
||||
|
||||
report__warn_kptr_restrict(rep);
|
||||
|
||||
evlist__for_each(session->evlist, pos)
|
||||
evlist__for_each_entry(session->evlist, pos)
|
||||
rep->nr_entries += evsel__hists(pos)->nr_entries;
|
||||
|
||||
if (use_browser == 0) {
|
||||
@ -583,7 +583,7 @@ static int __cmd_report(struct report *rep)
|
||||
* might be changed during the collapse phase.
|
||||
*/
|
||||
rep->nr_entries = 0;
|
||||
evlist__for_each(session->evlist, pos)
|
||||
evlist__for_each_entry(session->evlist, pos)
|
||||
rep->nr_entries += evsel__hists(pos)->nr_entries;
|
||||
|
||||
if (rep->nr_entries == 0) {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "util/cpumap.h"
|
||||
#include "util/thread_map.h"
|
||||
#include "util/stat.h"
|
||||
#include "util/thread-stack.h"
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/stringify.h>
|
||||
#include "asm/bug.h"
|
||||
@ -63,6 +64,7 @@ enum perf_output_field {
|
||||
PERF_OUTPUT_DATA_SRC = 1U << 17,
|
||||
PERF_OUTPUT_WEIGHT = 1U << 18,
|
||||
PERF_OUTPUT_BPF_OUTPUT = 1U << 19,
|
||||
PERF_OUTPUT_CALLINDENT = 1U << 20,
|
||||
};
|
||||
|
||||
struct output_option {
|
||||
@ -89,6 +91,7 @@ struct output_option {
|
||||
{.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},
|
||||
{.str = "weight", .field = PERF_OUTPUT_WEIGHT},
|
||||
{.str = "bpf-output", .field = PERF_OUTPUT_BPF_OUTPUT},
|
||||
{.str = "callindent", .field = PERF_OUTPUT_CALLINDENT},
|
||||
};
|
||||
|
||||
/* default set to maintain compatibility with current format */
|
||||
@ -369,7 +372,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
|
||||
if (!no_callchain) {
|
||||
bool use_callchain = false;
|
||||
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
|
||||
use_callchain = true;
|
||||
break;
|
||||
@ -389,7 +392,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
|
||||
|
||||
j = PERF_TYPE_TRACEPOINT;
|
||||
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (evsel->attr.type != j)
|
||||
continue;
|
||||
|
||||
@ -562,6 +565,62 @@ static void print_sample_addr(struct perf_sample *sample,
|
||||
}
|
||||
}
|
||||
|
||||
static void print_sample_callindent(struct perf_sample *sample,
|
||||
struct perf_evsel *evsel,
|
||||
struct thread *thread,
|
||||
struct addr_location *al)
|
||||
{
|
||||
struct perf_event_attr *attr = &evsel->attr;
|
||||
size_t depth = thread_stack__depth(thread);
|
||||
struct addr_location addr_al;
|
||||
const char *name = NULL;
|
||||
static int spacing;
|
||||
int len = 0;
|
||||
u64 ip = 0;
|
||||
|
||||
/*
|
||||
* The 'return' has already been popped off the stack so the depth has
|
||||
* to be adjusted to match the 'call'.
|
||||
*/
|
||||
if (thread->ts && sample->flags & PERF_IP_FLAG_RETURN)
|
||||
depth += 1;
|
||||
|
||||
if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) {
|
||||
if (sample_addr_correlates_sym(attr)) {
|
||||
thread__resolve(thread, &addr_al, sample);
|
||||
if (addr_al.sym)
|
||||
name = addr_al.sym->name;
|
||||
else
|
||||
ip = sample->addr;
|
||||
} else {
|
||||
ip = sample->addr;
|
||||
}
|
||||
} else if (sample->flags & (PERF_IP_FLAG_RETURN | PERF_IP_FLAG_TRACE_END)) {
|
||||
if (al->sym)
|
||||
name = al->sym->name;
|
||||
else
|
||||
ip = sample->ip;
|
||||
}
|
||||
|
||||
if (name)
|
||||
len = printf("%*s%s", (int)depth * 4, "", name);
|
||||
else if (ip)
|
||||
len = printf("%*s%16" PRIx64, (int)depth * 4, "", ip);
|
||||
|
||||
if (len < 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Try to keep the output length from changing frequently so that the
|
||||
* output lines up more nicely.
|
||||
*/
|
||||
if (len > spacing || (len && len < spacing - 52))
|
||||
spacing = round_up(len + 4, 32);
|
||||
|
||||
if (len < spacing)
|
||||
printf("%*s", spacing - len, "");
|
||||
}
|
||||
|
||||
static void print_sample_bts(struct perf_sample *sample,
|
||||
struct perf_evsel *evsel,
|
||||
struct thread *thread,
|
||||
@ -570,6 +629,9 @@ static void print_sample_bts(struct perf_sample *sample,
|
||||
struct perf_event_attr *attr = &evsel->attr;
|
||||
bool print_srcline_last = false;
|
||||
|
||||
if (PRINT_FIELD(CALLINDENT))
|
||||
print_sample_callindent(sample, evsel, thread, al);
|
||||
|
||||
/* print branch_from information */
|
||||
if (PRINT_FIELD(IP)) {
|
||||
unsigned int print_opts = output[attr->type].print_ip_opts;
|
||||
@ -606,13 +668,42 @@ static void print_sample_bts(struct perf_sample *sample,
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static struct {
|
||||
u32 flags;
|
||||
const char *name;
|
||||
} sample_flags[] = {
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"},
|
||||
{PERF_IP_FLAG_BRANCH, "jmp"},
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"},
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"},
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"},
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"},
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"},
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT, "hw int"},
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"},
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"},
|
||||
{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static void print_sample_flags(u32 flags)
|
||||
{
|
||||
const char *chars = PERF_IP_FLAG_CHARS;
|
||||
const int n = strlen(PERF_IP_FLAG_CHARS);
|
||||
bool in_tx = flags & PERF_IP_FLAG_IN_TX;
|
||||
const char *name = NULL;
|
||||
char str[33];
|
||||
int i, pos = 0;
|
||||
|
||||
for (i = 0; sample_flags[i].name ; i++) {
|
||||
if (sample_flags[i].flags == (flags & ~PERF_IP_FLAG_IN_TX)) {
|
||||
name = sample_flags[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++, flags >>= 1) {
|
||||
if (flags & 1)
|
||||
str[pos++] = chars[i];
|
||||
@ -622,7 +713,11 @@ static void print_sample_flags(u32 flags)
|
||||
str[pos++] = '?';
|
||||
}
|
||||
str[pos] = 0;
|
||||
printf(" %-4s ", str);
|
||||
|
||||
if (name)
|
||||
printf(" %-7s%4s ", name, in_tx ? "(x)" : "");
|
||||
else
|
||||
printf(" %-11s ", str);
|
||||
}
|
||||
|
||||
struct printer_data {
|
||||
@ -720,7 +815,7 @@ static int perf_evlist__max_name_len(struct perf_evlist *evlist)
|
||||
struct perf_evsel *evsel;
|
||||
int max = 0;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
int len = strlen(perf_evsel__name(evsel));
|
||||
|
||||
max = MAX(len, max);
|
||||
@ -945,7 +1040,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
|
||||
if (evsel->attr.type >= PERF_TYPE_MAX)
|
||||
return 0;
|
||||
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
if (pos->attr.type == evsel->attr.type && pos != evsel)
|
||||
return 0;
|
||||
}
|
||||
@ -1671,7 +1766,7 @@ static int check_ev_match(char *dir_name, char *scriptname,
|
||||
snprintf(evname, len + 1, "%s", p);
|
||||
|
||||
match = 0;
|
||||
evlist__for_each(session->evlist, pos) {
|
||||
evlist__for_each_entry(session->evlist, pos) {
|
||||
if (!strcmp(perf_evsel__name(pos), evname)) {
|
||||
match = 1;
|
||||
break;
|
||||
@ -1873,7 +1968,7 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
|
||||
struct stat_round_event *round = &event->stat_round;
|
||||
struct perf_evsel *counter;
|
||||
|
||||
evlist__for_each(session->evlist, counter) {
|
||||
evlist__for_each_entry(session->evlist, counter) {
|
||||
perf_stat_process_counter(&stat_config, counter);
|
||||
process_stat(counter, round->time);
|
||||
}
|
||||
@ -2020,7 +2115,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
"comma separated output fields prepend with 'type:'. "
|
||||
"Valid types: hw,sw,trace,raw. "
|
||||
"Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
|
||||
"addr,symoff,period,iregs,brstack,brstacksym,flags", parse_output_fields),
|
||||
"addr,symoff,period,iregs,brstack,brstacksym,flags,"
|
||||
"callindent", parse_output_fields),
|
||||
OPT_BOOLEAN('a', "all-cpus", &system_wide,
|
||||
"system-wide collection from all CPUs"),
|
||||
OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
|
||||
@ -2259,6 +2355,9 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
script.session = session;
|
||||
script__setup_sample_type(&script);
|
||||
|
||||
if (output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT)
|
||||
itrace_synth_opts.thread_stack = true;
|
||||
|
||||
session->itrace_synth_opts = &itrace_synth_opts;
|
||||
|
||||
if (cpu_list) {
|
||||
|
@ -331,7 +331,7 @@ static void read_counters(bool close_counters)
|
||||
{
|
||||
struct perf_evsel *counter;
|
||||
|
||||
evlist__for_each(evsel_list, counter) {
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
if (read_counter(counter))
|
||||
pr_debug("failed to read counter %s\n", counter->name);
|
||||
|
||||
@ -417,7 +417,7 @@ static int perf_stat_synthesize_config(bool is_pipe)
|
||||
* Synthesize other events stuff not carried within
|
||||
* attr event - unit, scale, name
|
||||
*/
|
||||
evlist__for_each(evsel_list, counter) {
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
if (!counter->supported)
|
||||
continue;
|
||||
|
||||
@ -550,7 +550,7 @@ static int __run_perf_stat(int argc, const char **argv)
|
||||
if (group)
|
||||
perf_evlist__set_leader(evsel_list);
|
||||
|
||||
evlist__for_each(evsel_list, counter) {
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
try_again:
|
||||
if (create_perf_stat_counter(counter) < 0) {
|
||||
/*
|
||||
@ -1134,7 +1134,7 @@ static void aggr_update_shadow(void)
|
||||
|
||||
for (s = 0; s < aggr_map->nr; s++) {
|
||||
id = aggr_map->map[s];
|
||||
evlist__for_each(evsel_list, counter) {
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
val = 0;
|
||||
for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
|
||||
s2 = aggr_get_id(evsel_list->cpus, cpu);
|
||||
@ -1173,7 +1173,7 @@ static void print_aggr(char *prefix)
|
||||
|
||||
id = aggr_map->map[s];
|
||||
first = true;
|
||||
evlist__for_each(evsel_list, counter) {
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
val = ena = run = 0;
|
||||
nr = 0;
|
||||
for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
|
||||
@ -1292,7 +1292,7 @@ static void print_no_aggr_metric(char *prefix)
|
||||
|
||||
if (prefix)
|
||||
fputs(prefix, stat_config.output);
|
||||
evlist__for_each(evsel_list, counter) {
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
if (first) {
|
||||
aggr_printout(counter, cpu, 0);
|
||||
first = false;
|
||||
@ -1346,7 +1346,7 @@ static void print_metric_headers(const char *prefix, bool no_indent)
|
||||
}
|
||||
|
||||
/* Print metrics headers only */
|
||||
evlist__for_each(evsel_list, counter) {
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
os.evsel = counter;
|
||||
out.ctx = &os;
|
||||
out.print_metric = print_metric_header;
|
||||
@ -1482,11 +1482,11 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
|
||||
print_aggr(prefix);
|
||||
break;
|
||||
case AGGR_THREAD:
|
||||
evlist__for_each(evsel_list, counter)
|
||||
evlist__for_each_entry(evsel_list, counter)
|
||||
print_aggr_thread(counter, prefix);
|
||||
break;
|
||||
case AGGR_GLOBAL:
|
||||
evlist__for_each(evsel_list, counter)
|
||||
evlist__for_each_entry(evsel_list, counter)
|
||||
print_counter_aggr(counter, prefix);
|
||||
if (metric_only)
|
||||
fputc('\n', stat_config.output);
|
||||
@ -1495,7 +1495,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
|
||||
if (metric_only)
|
||||
print_no_aggr_metric(prefix);
|
||||
else {
|
||||
evlist__for_each(evsel_list, counter)
|
||||
evlist__for_each_entry(evsel_list, counter)
|
||||
print_counter(counter, prefix);
|
||||
}
|
||||
break;
|
||||
@ -2149,7 +2149,7 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
|
||||
const char **argv = session->header.env.cmdline_argv;
|
||||
int argc = session->header.env.nr_cmdline;
|
||||
|
||||
evlist__for_each(evsel_list, counter)
|
||||
evlist__for_each_entry(evsel_list, counter)
|
||||
perf_stat_process_counter(&stat_config, counter);
|
||||
|
||||
if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL)
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "perf.h"
|
||||
|
||||
#include "util/annotate.h"
|
||||
#include "util/cache.h"
|
||||
#include "util/config.h"
|
||||
#include "util/color.h"
|
||||
#include "util/evlist.h"
|
||||
#include "util/evsel.h"
|
||||
@ -479,7 +479,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
|
||||
|
||||
fprintf(stderr, "\nAvailable events:");
|
||||
|
||||
evlist__for_each(top->evlist, top->sym_evsel)
|
||||
evlist__for_each_entry(top->evlist, top->sym_evsel)
|
||||
fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel));
|
||||
|
||||
prompt_integer(&counter, "Enter details event counter");
|
||||
@ -490,7 +490,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
|
||||
sleep(1);
|
||||
break;
|
||||
}
|
||||
evlist__for_each(top->evlist, top->sym_evsel)
|
||||
evlist__for_each_entry(top->evlist, top->sym_evsel)
|
||||
if (top->sym_evsel->idx == counter)
|
||||
break;
|
||||
} else
|
||||
@ -583,7 +583,7 @@ static void *display_thread_tui(void *arg)
|
||||
* Zooming in/out UIDs. For now juse use whatever the user passed
|
||||
* via --uid.
|
||||
*/
|
||||
evlist__for_each(top->evlist, pos) {
|
||||
evlist__for_each_entry(top->evlist, pos) {
|
||||
struct hists *hists = evsel__hists(pos);
|
||||
hists->uid_filter_str = top->record_opts.target.uid_str;
|
||||
}
|
||||
@ -888,7 +888,7 @@ static int perf_top__start_counters(struct perf_top *top)
|
||||
|
||||
perf_evlist__config(evlist, opts, &callchain_param);
|
||||
|
||||
evlist__for_each(evlist, counter) {
|
||||
evlist__for_each_entry(evlist, counter) {
|
||||
try_again:
|
||||
if (perf_evsel__open(counter, top->evlist->cpus,
|
||||
top->evlist->threads) < 0) {
|
||||
|
@ -1247,7 +1247,7 @@ static int trace__validate_ev_qualifier(struct trace *trace)
|
||||
|
||||
i = 0;
|
||||
|
||||
strlist__for_each(pos, trace->ev_qualifier) {
|
||||
strlist__for_each_entry(pos, trace->ev_qualifier) {
|
||||
const char *sc = pos->s;
|
||||
int id = syscalltbl__id(trace->sctbl, sc);
|
||||
|
||||
@ -2483,7 +2483,7 @@ static int trace__replay(struct trace *trace)
|
||||
goto out;
|
||||
}
|
||||
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (evsel->attr.type == PERF_TYPE_SOFTWARE &&
|
||||
(evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ||
|
||||
evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MIN ||
|
||||
@ -2550,7 +2550,7 @@ static size_t thread__dump_stats(struct thread_trace *ttrace,
|
||||
printed += fprintf(fp, " (msec) (msec) (msec) (msec) (%%)\n");
|
||||
printed += fprintf(fp, " --------------- -------- --------- --------- --------- --------- ------\n");
|
||||
|
||||
resort_rb__for_each(nd, syscall_stats) {
|
||||
resort_rb__for_each_entry(nd, syscall_stats) {
|
||||
struct stats *stats = syscall_stats_entry->stats;
|
||||
if (stats) {
|
||||
double min = (double)(stats->min) / NSEC_PER_MSEC;
|
||||
@ -2627,7 +2627,7 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
resort_rb__for_each(nd, threads)
|
||||
resort_rb__for_each_entry(nd, threads)
|
||||
printed += trace__fprintf_thread(fp, threads_entry->thread, trace);
|
||||
|
||||
resort_rb__delete(threads);
|
||||
@ -2714,7 +2714,7 @@ static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
evsel->handler = handler;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "util/env.h"
|
||||
#include <subcmd/exec-cmd.h>
|
||||
#include "util/cache.h"
|
||||
#include "util/config.h"
|
||||
#include "util/quote.h"
|
||||
#include <subcmd/run-command.h>
|
||||
#include "util/parse-events.h"
|
||||
@ -355,6 +355,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
|
||||
|
||||
perf_env__set_cmdline(&perf_env, argc, argv);
|
||||
status = p->fn(argc, argv, prefix);
|
||||
perf_config__exit();
|
||||
exit_browser(status);
|
||||
perf_env__exit(&perf_env);
|
||||
bpf__clear();
|
||||
@ -522,6 +523,7 @@ int main(int argc, const char **argv)
|
||||
|
||||
srandom(time(NULL));
|
||||
|
||||
perf_config__init();
|
||||
perf_config(perf_default_config, NULL);
|
||||
set_buildid_dir(NULL);
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# stackcollapse.py - format perf samples with one line per distinct call stack
|
||||
#
|
||||
# This script's output has two space-separated fields. The first is a semicolon
|
||||
|
@ -118,7 +118,7 @@ int test__backward_ring_buffer(int subtest __maybe_unused)
|
||||
perf_evlist__config(evlist, &opts, NULL);
|
||||
|
||||
/* Set backward bit, ring buffer should be writing from end */
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
evsel->attr.write_backward = 1;
|
||||
|
||||
err = perf_evlist__open(evlist);
|
||||
|
@ -200,8 +200,7 @@ static int test_times(int (attach)(struct perf_evlist *),
|
||||
count.ena, count.run);
|
||||
|
||||
out_err:
|
||||
if (evlist)
|
||||
perf_evlist__delete(evlist);
|
||||
perf_evlist__delete(evlist);
|
||||
return !err ? TEST_OK : TEST_FAIL;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names)
|
||||
}
|
||||
|
||||
err = 0;
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) {
|
||||
--err;
|
||||
pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]);
|
||||
|
@ -56,7 +56,7 @@ static int add_hist_entries(struct perf_evlist *evlist,
|
||||
* (perf [perf] main) will be collapsed to an existing entry
|
||||
* so total 9 entries will be in the tree.
|
||||
*/
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
|
||||
struct hist_entry_iter iter = {
|
||||
.evsel = evsel,
|
||||
@ -136,7 +136,7 @@ int test__hists_filter(int subtest __maybe_unused)
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
struct hists *hists = evsel__hists(evsel);
|
||||
|
||||
hists__collapse_resort(hists, NULL);
|
||||
|
@ -72,7 +72,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
|
||||
* However the second evsel also has a collapsed entry for
|
||||
* "bash [libc] malloc" so total 9 entries will be in the tree.
|
||||
*/
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
struct hists *hists = evsel__hists(evsel);
|
||||
|
||||
for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) {
|
||||
@ -301,7 +301,7 @@ int test__hists_link(int subtest __maybe_unused)
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
hists = evsel__hists(evsel);
|
||||
hists__collapse_resort(hists, NULL);
|
||||
|
||||
|
@ -126,7 +126,7 @@ int test__basic_mmap(int subtest __maybe_unused)
|
||||
}
|
||||
|
||||
err = 0;
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
|
||||
pr_debug("expected %d %s events, got %d\n",
|
||||
expected_nr_events[evsel->idx],
|
||||
|
@ -32,7 +32,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)
|
||||
TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
|
||||
TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups);
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
TEST_ASSERT_VAL("wrong type",
|
||||
PERF_TYPE_TRACEPOINT == evsel->attr.type);
|
||||
TEST_ASSERT_VAL("wrong sample_type",
|
||||
@ -207,7 +207,7 @@ test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist)
|
||||
|
||||
TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
TEST_ASSERT_VAL("wrong exclude_user",
|
||||
!evsel->attr.exclude_user);
|
||||
TEST_ASSERT_VAL("wrong exclude_kernel",
|
||||
|
@ -44,8 +44,7 @@ static int process_events(union perf_event **events, size_t count)
|
||||
for (i = 0; i < count && !err; i++)
|
||||
err = process_event(&evlist, events[i]);
|
||||
|
||||
if (evlist)
|
||||
perf_evlist__delete(evlist);
|
||||
perf_evlist__delete(evlist);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ int test__switch_tracking(int subtest __maybe_unused)
|
||||
}
|
||||
|
||||
/* Check non-tracking events are not tracking */
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel != tracking_evsel) {
|
||||
if (evsel->attr.mmap || evsel->attr.comm) {
|
||||
pr_debug("Non-tracking event is tracking\n");
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "../util.h"
|
||||
#include "../cache.h"
|
||||
#include "../config.h"
|
||||
#include "../../perf.h"
|
||||
#include "libslang.h"
|
||||
#include "ui.h"
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "../../util/sort.h"
|
||||
#include "../../util/symbol.h"
|
||||
#include "../../util/evsel.h"
|
||||
#include "../../util/config.h"
|
||||
#include <pthread.h>
|
||||
|
||||
struct disasm_line_samples {
|
||||
|
@ -12,35 +12,17 @@
|
||||
#include "../../util/top.h"
|
||||
#include "../../arch/common.h"
|
||||
|
||||
#include "../browser.h"
|
||||
#include "../browsers/hists.h"
|
||||
#include "../helpline.h"
|
||||
#include "../util.h"
|
||||
#include "../ui.h"
|
||||
#include "map.h"
|
||||
#include "annotate.h"
|
||||
|
||||
struct hist_browser {
|
||||
struct ui_browser b;
|
||||
struct hists *hists;
|
||||
struct hist_entry *he_selection;
|
||||
struct map_symbol *selection;
|
||||
struct hist_browser_timer *hbt;
|
||||
struct pstack *pstack;
|
||||
struct perf_env *env;
|
||||
int print_seq;
|
||||
bool show_dso;
|
||||
bool show_headers;
|
||||
float min_pcnt;
|
||||
u64 nr_non_filtered_entries;
|
||||
u64 nr_hierarchy_entries;
|
||||
u64 nr_callchain_rows;
|
||||
};
|
||||
|
||||
extern void hist_browser__init_hpp(void);
|
||||
|
||||
static int hists__browser_title(struct hists *hists,
|
||||
struct hist_browser_timer *hbt,
|
||||
char *bf, size_t size);
|
||||
static int perf_evsel_browser_title(struct hist_browser *browser,
|
||||
char *bf, size_t size);
|
||||
static void hist_browser__update_nr_entries(struct hist_browser *hb);
|
||||
|
||||
static struct rb_node *hists__filter_entries(struct rb_node *nd,
|
||||
@ -585,7 +567,12 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
|
||||
"Or reduce the sampling frequency.");
|
||||
}
|
||||
|
||||
static int hist_browser__run(struct hist_browser *browser, const char *help)
|
||||
static int hist_browser__title(struct hist_browser *browser, char *bf, size_t size)
|
||||
{
|
||||
return browser->title ? browser->title(browser, bf, size) : 0;
|
||||
}
|
||||
|
||||
int hist_browser__run(struct hist_browser *browser, const char *help)
|
||||
{
|
||||
int key;
|
||||
char title[160];
|
||||
@ -595,7 +582,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *help)
|
||||
browser->b.entries = &browser->hists->entries;
|
||||
browser->b.nr_entries = hist_browser__nr_entries(browser);
|
||||
|
||||
hists__browser_title(browser->hists, hbt, title, sizeof(title));
|
||||
hist_browser__title(browser, title, sizeof(title));
|
||||
|
||||
if (ui_browser__show(&browser->b, title, "%s", help) < 0)
|
||||
return -1;
|
||||
@ -621,8 +608,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *help)
|
||||
ui_browser__warn_lost_events(&browser->b);
|
||||
}
|
||||
|
||||
hists__browser_title(browser->hists,
|
||||
hbt, title, sizeof(title));
|
||||
hist_browser__title(browser, title, sizeof(title));
|
||||
ui_browser__show_title(&browser->b, title);
|
||||
continue;
|
||||
}
|
||||
@ -2056,27 +2042,50 @@ static int hist_browser__dump(struct hist_browser *browser)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct hist_browser *hist_browser__new(struct hists *hists,
|
||||
struct hist_browser_timer *hbt,
|
||||
struct perf_env *env)
|
||||
void hist_browser__init(struct hist_browser *browser,
|
||||
struct hists *hists)
|
||||
{
|
||||
struct perf_hpp_fmt *fmt;
|
||||
|
||||
browser->hists = hists;
|
||||
browser->b.refresh = hist_browser__refresh;
|
||||
browser->b.refresh_dimensions = hist_browser__refresh_dimensions;
|
||||
browser->b.seek = ui_browser__hists_seek;
|
||||
browser->b.use_navkeypressed = true;
|
||||
browser->show_headers = symbol_conf.show_hist_headers;
|
||||
|
||||
hists__for_each_format(hists, fmt) {
|
||||
perf_hpp__reset_width(fmt, hists);
|
||||
++browser->b.columns;
|
||||
}
|
||||
}
|
||||
|
||||
struct hist_browser *hist_browser__new(struct hists *hists)
|
||||
{
|
||||
struct hist_browser *browser = zalloc(sizeof(*browser));
|
||||
|
||||
if (browser) {
|
||||
browser->hists = hists;
|
||||
browser->b.refresh = hist_browser__refresh;
|
||||
browser->b.refresh_dimensions = hist_browser__refresh_dimensions;
|
||||
browser->b.seek = ui_browser__hists_seek;
|
||||
browser->b.use_navkeypressed = true;
|
||||
browser->show_headers = symbol_conf.show_hist_headers;
|
||||
browser->hbt = hbt;
|
||||
browser->env = env;
|
||||
}
|
||||
if (browser)
|
||||
hist_browser__init(browser, hists);
|
||||
|
||||
return browser;
|
||||
}
|
||||
|
||||
static void hist_browser__delete(struct hist_browser *browser)
|
||||
static struct hist_browser *
|
||||
perf_evsel_browser__new(struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt,
|
||||
struct perf_env *env)
|
||||
{
|
||||
struct hist_browser *browser = hist_browser__new(evsel__hists(evsel));
|
||||
|
||||
if (browser) {
|
||||
browser->hbt = hbt;
|
||||
browser->env = env;
|
||||
browser->title = perf_evsel_browser_title;
|
||||
}
|
||||
return browser;
|
||||
}
|
||||
|
||||
void hist_browser__delete(struct hist_browser *browser)
|
||||
{
|
||||
free(browser);
|
||||
}
|
||||
@ -2097,10 +2106,11 @@ static inline bool is_report_browser(void *timer)
|
||||
return timer == NULL;
|
||||
}
|
||||
|
||||
static int hists__browser_title(struct hists *hists,
|
||||
struct hist_browser_timer *hbt,
|
||||
static int perf_evsel_browser_title(struct hist_browser *browser,
|
||||
char *bf, size_t size)
|
||||
{
|
||||
struct hist_browser_timer *hbt = browser->hbt;
|
||||
struct hists *hists = browser->hists;
|
||||
char unit;
|
||||
int printed;
|
||||
const struct dso *dso = hists->dso_filter;
|
||||
@ -2657,7 +2667,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
|
||||
struct perf_env *env)
|
||||
{
|
||||
struct hists *hists = evsel__hists(evsel);
|
||||
struct hist_browser *browser = hist_browser__new(hists, hbt, env);
|
||||
struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env);
|
||||
struct branch_info *bi;
|
||||
#define MAX_OPTIONS 16
|
||||
char *options[MAX_OPTIONS];
|
||||
@ -2666,7 +2676,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
|
||||
int key = -1;
|
||||
char buf[64];
|
||||
int delay_secs = hbt ? hbt->refresh : 0;
|
||||
struct perf_hpp_fmt *fmt;
|
||||
|
||||
#define HIST_BROWSER_HELP_COMMON \
|
||||
"h/?/F1 Show this window\n" \
|
||||
@ -2725,18 +2734,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
|
||||
memset(options, 0, sizeof(options));
|
||||
memset(actions, 0, sizeof(actions));
|
||||
|
||||
hists__for_each_format(browser->hists, fmt) {
|
||||
perf_hpp__reset_width(fmt, hists);
|
||||
/*
|
||||
* This is done just once, and activates the horizontal scrolling
|
||||
* code in the ui_browser code, it would be better to have a the
|
||||
* counter in the perf_hpp code, but I couldn't find doing it here
|
||||
* works, FIXME by setting this in hist_browser__new, for now, be
|
||||
* clever 8-)
|
||||
*/
|
||||
++browser->b.columns;
|
||||
}
|
||||
|
||||
if (symbol_conf.col_width_list_str)
|
||||
perf_hpp__set_user_width(symbol_conf.col_width_list_str);
|
||||
|
||||
@ -3202,7 +3199,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
|
||||
|
||||
ui_helpline__push("Press ESC to exit");
|
||||
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
const char *ev_name = perf_evsel__name(pos);
|
||||
size_t line_len = strlen(ev_name) + 7;
|
||||
|
||||
@ -3233,7 +3230,7 @@ single_entry:
|
||||
struct perf_evsel *pos;
|
||||
|
||||
nr_entries = 0;
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
if (perf_evsel__is_group_leader(pos))
|
||||
nr_entries++;
|
||||
}
|
||||
|
32
tools/perf/ui/browsers/hists.h
Normal file
32
tools/perf/ui/browsers/hists.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef _PERF_UI_BROWSER_HISTS_H_
|
||||
#define _PERF_UI_BROWSER_HISTS_H_ 1
|
||||
|
||||
#include "ui/browser.h"
|
||||
|
||||
struct hist_browser {
|
||||
struct ui_browser b;
|
||||
struct hists *hists;
|
||||
struct hist_entry *he_selection;
|
||||
struct map_symbol *selection;
|
||||
struct hist_browser_timer *hbt;
|
||||
struct pstack *pstack;
|
||||
struct perf_env *env;
|
||||
int print_seq;
|
||||
bool show_dso;
|
||||
bool show_headers;
|
||||
float min_pcnt;
|
||||
u64 nr_non_filtered_entries;
|
||||
u64 nr_hierarchy_entries;
|
||||
u64 nr_callchain_rows;
|
||||
|
||||
/* Get title string. */
|
||||
int (*title)(struct hist_browser *browser,
|
||||
char *bf, size_t size);
|
||||
};
|
||||
|
||||
struct hist_browser *hist_browser__new(struct hists *hists);
|
||||
void hist_browser__delete(struct hist_browser *browser);
|
||||
int hist_browser__run(struct hist_browser *browser, const char *help);
|
||||
void hist_browser__init(struct hist_browser *browser,
|
||||
struct hists *hists);
|
||||
#endif /* _PERF_UI_BROWSER_HISTS_H_ */
|
@ -627,7 +627,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(window), vbox);
|
||||
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
struct hists *hists = evsel__hists(pos);
|
||||
const char *evname = perf_evsel__name(pos);
|
||||
GtkWidget *scrolled_window;
|
||||
|
@ -766,7 +766,7 @@ int perf_hpp__setup_hists_formats(struct perf_hpp_list *list,
|
||||
if (!symbol_conf.report_hierarchy)
|
||||
return 0;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
hists = evsel__hists(evsel);
|
||||
|
||||
perf_hpp_list__for_each_sort_list(list, fmt) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "cache.h"
|
||||
#include "config.h"
|
||||
|
||||
static const char *alias_key;
|
||||
static char *alias_val;
|
||||
|
@ -63,6 +63,7 @@ enum itrace_period_type {
|
||||
* @calls: limit branch samples to calls (can be combined with @returns)
|
||||
* @returns: limit branch samples to returns (can be combined with @calls)
|
||||
* @callchain: add callchain to 'instructions' events
|
||||
* @thread_stack: feed branches to the thread_stack
|
||||
* @last_branch: add branch context to 'instruction' events
|
||||
* @callchain_sz: maximum callchain size
|
||||
* @last_branch_sz: branch context size
|
||||
@ -82,6 +83,7 @@ struct itrace_synth_opts {
|
||||
bool calls;
|
||||
bool returns;
|
||||
bool callchain;
|
||||
bool thread_stack;
|
||||
bool last_branch;
|
||||
unsigned int callchain_sz;
|
||||
unsigned int last_branch_sz;
|
||||
|
@ -18,17 +18,6 @@
|
||||
#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
|
||||
#define PERF_PAGER_ENVIRONMENT "PERF_PAGER"
|
||||
|
||||
extern const char *config_exclusive_filename;
|
||||
|
||||
typedef int (*config_fn_t)(const char *, const char *, void *);
|
||||
int perf_default_config(const char *, const char *, void *);
|
||||
int perf_config(config_fn_t fn, void *);
|
||||
int perf_config_int(const char *, const char *);
|
||||
u64 perf_config_u64(const char *, const char *);
|
||||
int perf_config_bool(const char *, const char *);
|
||||
int config_error_nonbool(const char *);
|
||||
const char *perf_etc_perfconfig(void);
|
||||
|
||||
char *alias_lookup(const char *alias);
|
||||
int split_cmdline(char *cmdline, const char ***argv);
|
||||
|
||||
|
@ -81,7 +81,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str)
|
||||
/*
|
||||
* check if cgrp is already defined, if so we reuse it
|
||||
*/
|
||||
evlist__for_each(evlist, counter) {
|
||||
evlist__for_each_entry(evlist, counter) {
|
||||
cgrp = counter->cgrp;
|
||||
if (!cgrp)
|
||||
continue;
|
||||
@ -110,7 +110,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str)
|
||||
* if add cgroup N, then need to find event N
|
||||
*/
|
||||
n = 0;
|
||||
evlist__for_each(evlist, counter) {
|
||||
evlist__for_each_entry(evlist, counter) {
|
||||
if (n == nr_cgroups)
|
||||
goto found;
|
||||
n++;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <linux/kernel.h>
|
||||
#include "cache.h"
|
||||
#include "config.h"
|
||||
#include "color.h"
|
||||
#include <math.h>
|
||||
|
||||
|
@ -26,6 +26,7 @@ static FILE *config_file;
|
||||
static const char *config_file_name;
|
||||
static int config_linenr;
|
||||
static int config_file_eof;
|
||||
static struct perf_config_set *config_set;
|
||||
|
||||
const char *config_exclusive_filename;
|
||||
|
||||
@ -478,51 +479,6 @@ static int perf_config_global(void)
|
||||
return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0);
|
||||
}
|
||||
|
||||
int perf_config(config_fn_t fn, void *data)
|
||||
{
|
||||
int ret = -1;
|
||||
const char *home = NULL;
|
||||
|
||||
/* Setting $PERF_CONFIG makes perf read _only_ the given config file. */
|
||||
if (config_exclusive_filename)
|
||||
return perf_config_from_file(fn, config_exclusive_filename, data);
|
||||
if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) {
|
||||
if (perf_config_from_file(fn, perf_etc_perfconfig(), data) < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
home = getenv("HOME");
|
||||
if (perf_config_global() && home) {
|
||||
char *user_config = strdup(mkpath("%s/.perfconfig", home));
|
||||
struct stat st;
|
||||
|
||||
if (user_config == NULL) {
|
||||
warning("Not enough memory to process %s/.perfconfig, "
|
||||
"ignoring it.", home);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (stat(user_config, &st) < 0)
|
||||
goto out_free;
|
||||
|
||||
if (st.st_uid && (st.st_uid != geteuid())) {
|
||||
warning("File %s not owned by current user or root, "
|
||||
"ignoring it.", user_config);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (!st.st_size)
|
||||
goto out_free;
|
||||
|
||||
ret = perf_config_from_file(fn, user_config, data);
|
||||
|
||||
out_free:
|
||||
free(user_config);
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct perf_config_section *find_section(struct list_head *sections,
|
||||
const char *section_name)
|
||||
{
|
||||
@ -706,6 +662,52 @@ struct perf_config_set *perf_config_set__new(void)
|
||||
return set;
|
||||
}
|
||||
|
||||
int perf_config(config_fn_t fn, void *data)
|
||||
{
|
||||
int ret = 0;
|
||||
char key[BUFSIZ];
|
||||
struct perf_config_section *section;
|
||||
struct perf_config_item *item;
|
||||
|
||||
if (config_set == NULL)
|
||||
return -1;
|
||||
|
||||
perf_config_set__for_each_entry(config_set, section, item) {
|
||||
char *value = item->value;
|
||||
|
||||
if (value) {
|
||||
scnprintf(key, sizeof(key), "%s.%s",
|
||||
section->name, item->name);
|
||||
ret = fn(key, value, data);
|
||||
if (ret < 0) {
|
||||
pr_err("Error: wrong config key-value pair %s=%s\n",
|
||||
key, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void perf_config__init(void)
|
||||
{
|
||||
if (config_set == NULL)
|
||||
config_set = perf_config_set__new();
|
||||
}
|
||||
|
||||
void perf_config__exit(void)
|
||||
{
|
||||
perf_config_set__delete(config_set);
|
||||
config_set = NULL;
|
||||
}
|
||||
|
||||
void perf_config__refresh(void)
|
||||
{
|
||||
perf_config__exit();
|
||||
perf_config__init();
|
||||
}
|
||||
|
||||
static void perf_config_item__delete(struct perf_config_item *item)
|
||||
{
|
||||
zfree(&item->name);
|
||||
|
@ -20,7 +20,47 @@ struct perf_config_set {
|
||||
struct list_head sections;
|
||||
};
|
||||
|
||||
extern const char *config_exclusive_filename;
|
||||
|
||||
typedef int (*config_fn_t)(const char *, const char *, void *);
|
||||
int perf_default_config(const char *, const char *, void *);
|
||||
int perf_config(config_fn_t fn, void *);
|
||||
int perf_config_int(const char *, const char *);
|
||||
u64 perf_config_u64(const char *, const char *);
|
||||
int perf_config_bool(const char *, const char *);
|
||||
int config_error_nonbool(const char *);
|
||||
const char *perf_etc_perfconfig(void);
|
||||
|
||||
struct perf_config_set *perf_config_set__new(void);
|
||||
void perf_config_set__delete(struct perf_config_set *set);
|
||||
void perf_config__init(void);
|
||||
void perf_config__exit(void);
|
||||
void perf_config__refresh(void);
|
||||
|
||||
/**
|
||||
* perf_config_sections__for_each - iterate thru all the sections
|
||||
* @list: list_head instance to iterate
|
||||
* @section: struct perf_config_section iterator
|
||||
*/
|
||||
#define perf_config_sections__for_each_entry(list, section) \
|
||||
list_for_each_entry(section, list, node)
|
||||
|
||||
/**
|
||||
* perf_config_items__for_each - iterate thru all the items
|
||||
* @list: list_head instance to iterate
|
||||
* @item: struct perf_config_item iterator
|
||||
*/
|
||||
#define perf_config_items__for_each_entry(list, item) \
|
||||
list_for_each_entry(item, list, node)
|
||||
|
||||
/**
|
||||
* perf_config_set__for_each - iterate thru all the config section-item pairs
|
||||
* @set: evlist instance to iterate
|
||||
* @section: struct perf_config_section iterator
|
||||
* @item: struct perf_config_item iterator
|
||||
*/
|
||||
#define perf_config_set__for_each_entry(set, section, item) \
|
||||
perf_config_sections__for_each_entry(&set->sections, section) \
|
||||
perf_config_items__for_each_entry(§ion->items, item)
|
||||
|
||||
#endif /* __PERF_CONFIG_H */
|
||||
|
@ -997,7 +997,7 @@ static int setup_events(struct ctf_writer *cw, struct perf_session *session)
|
||||
struct perf_evsel *evsel;
|
||||
int ret;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
ret = add_event(cw, evsel);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -1010,7 +1010,7 @@ static void cleanup_events(struct perf_session *session)
|
||||
struct perf_evlist *evlist = session->evlist;
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
struct evsel_priv *priv;
|
||||
|
||||
priv = evsel->priv;
|
||||
|
@ -100,7 +100,7 @@ static void perf_evlist__update_id_pos(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
perf_evsel__calc_id_pos(evsel);
|
||||
|
||||
perf_evlist__set_id_pos(evlist);
|
||||
@ -110,7 +110,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *pos, *n;
|
||||
|
||||
evlist__for_each_safe(evlist, n, pos) {
|
||||
evlist__for_each_entry_safe(evlist, n, pos) {
|
||||
list_del_init(&pos->node);
|
||||
pos->evlist = NULL;
|
||||
perf_evsel__delete(pos);
|
||||
@ -127,6 +127,9 @@ void perf_evlist__exit(struct perf_evlist *evlist)
|
||||
|
||||
void perf_evlist__delete(struct perf_evlist *evlist)
|
||||
{
|
||||
if (evlist == NULL)
|
||||
return;
|
||||
|
||||
perf_evlist__munmap(evlist);
|
||||
perf_evlist__close(evlist);
|
||||
cpu_map__put(evlist->cpus);
|
||||
@ -161,7 +164,7 @@ static void perf_evlist__propagate_maps(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
__perf_evlist__propagate_maps(evlist, evsel);
|
||||
}
|
||||
|
||||
@ -190,7 +193,7 @@ void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
|
||||
{
|
||||
struct perf_evsel *evsel, *temp;
|
||||
|
||||
__evlist__for_each_safe(list, temp, evsel) {
|
||||
__evlist__for_each_entry_safe(list, temp, evsel) {
|
||||
list_del_init(&evsel->node);
|
||||
perf_evlist__add(evlist, evsel);
|
||||
}
|
||||
@ -205,7 +208,7 @@ void __perf_evlist__set_leader(struct list_head *list)
|
||||
|
||||
leader->nr_members = evsel->idx - leader->idx + 1;
|
||||
|
||||
__evlist__for_each(list, evsel) {
|
||||
__evlist__for_each_entry(list, evsel) {
|
||||
evsel->leader = leader;
|
||||
}
|
||||
}
|
||||
@ -296,7 +299,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist,
|
||||
return 0;
|
||||
|
||||
out_delete_partial_list:
|
||||
__evlist__for_each_safe(&head, n, evsel)
|
||||
__evlist__for_each_entry_safe(&head, n, evsel)
|
||||
perf_evsel__delete(evsel);
|
||||
return -1;
|
||||
}
|
||||
@ -317,7 +320,7 @@ perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.type == PERF_TYPE_TRACEPOINT &&
|
||||
(int)evsel->attr.config == id)
|
||||
return evsel;
|
||||
@ -332,7 +335,7 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) &&
|
||||
(strcmp(evsel->name, name) == 0))
|
||||
return evsel;
|
||||
@ -367,7 +370,7 @@ void perf_evlist__disable(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *pos;
|
||||
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
if (!perf_evsel__is_group_leader(pos) || !pos->fd)
|
||||
continue;
|
||||
perf_evsel__disable(pos);
|
||||
@ -380,7 +383,7 @@ void perf_evlist__enable(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *pos;
|
||||
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
if (!perf_evsel__is_group_leader(pos) || !pos->fd)
|
||||
continue;
|
||||
perf_evsel__enable(pos);
|
||||
@ -448,7 +451,7 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
|
||||
int nfds = 0;
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->system_wide)
|
||||
nfds += nr_cpus;
|
||||
else
|
||||
@ -1012,7 +1015,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
|
||||
struct perf_evsel *evsel;
|
||||
int revent;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
int fd;
|
||||
|
||||
if (evsel->overwrite != (evlist->overwrite && evlist->backward))
|
||||
@ -1259,7 +1262,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
|
||||
auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->mmap_len,
|
||||
auxtrace_pages, auxtrace_overwrite);
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
|
||||
evsel->sample_id == NULL &&
|
||||
perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0)
|
||||
@ -1335,7 +1338,7 @@ void __perf_evlist__set_sample_bit(struct perf_evlist *evlist,
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
__perf_evsel__set_sample_bit(evsel, bit);
|
||||
}
|
||||
|
||||
@ -1344,7 +1347,7 @@ void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist,
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
__perf_evsel__reset_sample_bit(evsel, bit);
|
||||
}
|
||||
|
||||
@ -1355,7 +1358,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e
|
||||
const int ncpus = cpu_map__nr(evlist->cpus),
|
||||
nthreads = thread_map__nr(evlist->threads);
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->filter == NULL)
|
||||
continue;
|
||||
|
||||
@ -1378,7 +1381,7 @@ int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter)
|
||||
struct perf_evsel *evsel;
|
||||
int err = 0;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
|
||||
continue;
|
||||
|
||||
@ -1432,7 +1435,7 @@ bool perf_evlist__valid_sample_type(struct perf_evlist *evlist)
|
||||
if (evlist->id_pos < 0 || evlist->is_pos < 0)
|
||||
return false;
|
||||
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
if (pos->id_pos != evlist->id_pos ||
|
||||
pos->is_pos != evlist->is_pos)
|
||||
return false;
|
||||
@ -1448,7 +1451,7 @@ u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist)
|
||||
if (evlist->combined_sample_type)
|
||||
return evlist->combined_sample_type;
|
||||
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
evlist->combined_sample_type |= evsel->attr.sample_type;
|
||||
|
||||
return evlist->combined_sample_type;
|
||||
@ -1465,7 +1468,7 @@ u64 perf_evlist__combined_branch_type(struct perf_evlist *evlist)
|
||||
struct perf_evsel *evsel;
|
||||
u64 branch_type = 0;
|
||||
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
branch_type |= evsel->attr.branch_sample_type;
|
||||
return branch_type;
|
||||
}
|
||||
@ -1476,7 +1479,7 @@ bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
|
||||
u64 read_format = first->attr.read_format;
|
||||
u64 sample_type = first->attr.sample_type;
|
||||
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
if (read_format != pos->attr.read_format)
|
||||
return false;
|
||||
}
|
||||
@ -1533,7 +1536,7 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
|
||||
|
||||
evlist__for_each_continue(evlist, pos) {
|
||||
evlist__for_each_entry_continue(evlist, pos) {
|
||||
if (first->attr.sample_id_all != pos->attr.sample_id_all)
|
||||
return false;
|
||||
}
|
||||
@ -1560,7 +1563,7 @@ void perf_evlist__close(struct perf_evlist *evlist)
|
||||
int nthreads = thread_map__nr(evlist->threads);
|
||||
int n;
|
||||
|
||||
evlist__for_each_reverse(evlist, evsel) {
|
||||
evlist__for_each_entry_reverse(evlist, evsel) {
|
||||
n = evsel->cpus ? evsel->cpus->nr : ncpus;
|
||||
perf_evsel__close(evsel, n, nthreads);
|
||||
}
|
||||
@ -1614,7 +1617,7 @@ int perf_evlist__open(struct perf_evlist *evlist)
|
||||
|
||||
perf_evlist__update_id_pos(evlist);
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
err = perf_evsel__open(evsel, evsel->cpus, evsel->threads);
|
||||
if (err < 0)
|
||||
goto out_err;
|
||||
@ -1775,7 +1778,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
|
||||
struct perf_evsel *evsel;
|
||||
size_t printed = 0;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "",
|
||||
perf_evsel__name(evsel));
|
||||
}
|
||||
@ -1877,7 +1880,7 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
|
||||
if (move_evsel == perf_evlist__first(evlist))
|
||||
return;
|
||||
|
||||
evlist__for_each_safe(evlist, n, evsel) {
|
||||
evlist__for_each_entry_safe(evlist, n, evsel) {
|
||||
if (evsel->leader == move_evsel->leader)
|
||||
list_move_tail(&evsel->node, &move);
|
||||
}
|
||||
@ -1893,7 +1896,7 @@ void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
|
||||
if (tracking_evsel->tracking)
|
||||
return;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel != tracking_evsel)
|
||||
evsel->tracking = false;
|
||||
}
|
||||
@ -1907,7 +1910,7 @@ perf_evlist__find_evsel_by_str(struct perf_evlist *evlist,
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (!evsel->name)
|
||||
continue;
|
||||
if (strcmp(str, evsel->name) == 0)
|
||||
|
@ -251,70 +251,70 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
|
||||
struct perf_evsel *move_evsel);
|
||||
|
||||
/**
|
||||
* __evlist__for_each - iterate thru all the evsels
|
||||
* __evlist__for_each_entry - iterate thru all the evsels
|
||||
* @list: list_head instance to iterate
|
||||
* @evsel: struct evsel iterator
|
||||
*/
|
||||
#define __evlist__for_each(list, evsel) \
|
||||
#define __evlist__for_each_entry(list, evsel) \
|
||||
list_for_each_entry(evsel, list, node)
|
||||
|
||||
/**
|
||||
* evlist__for_each - iterate thru all the evsels
|
||||
* evlist__for_each_entry - iterate thru all the evsels
|
||||
* @evlist: evlist instance to iterate
|
||||
* @evsel: struct evsel iterator
|
||||
*/
|
||||
#define evlist__for_each(evlist, evsel) \
|
||||
__evlist__for_each(&(evlist)->entries, evsel)
|
||||
#define evlist__for_each_entry(evlist, evsel) \
|
||||
__evlist__for_each_entry(&(evlist)->entries, evsel)
|
||||
|
||||
/**
|
||||
* __evlist__for_each_continue - continue iteration thru all the evsels
|
||||
* __evlist__for_each_entry_continue - continue iteration thru all the evsels
|
||||
* @list: list_head instance to iterate
|
||||
* @evsel: struct evsel iterator
|
||||
*/
|
||||
#define __evlist__for_each_continue(list, evsel) \
|
||||
#define __evlist__for_each_entry_continue(list, evsel) \
|
||||
list_for_each_entry_continue(evsel, list, node)
|
||||
|
||||
/**
|
||||
* evlist__for_each_continue - continue iteration thru all the evsels
|
||||
* evlist__for_each_entry_continue - continue iteration thru all the evsels
|
||||
* @evlist: evlist instance to iterate
|
||||
* @evsel: struct evsel iterator
|
||||
*/
|
||||
#define evlist__for_each_continue(evlist, evsel) \
|
||||
__evlist__for_each_continue(&(evlist)->entries, evsel)
|
||||
#define evlist__for_each_entry_continue(evlist, evsel) \
|
||||
__evlist__for_each_entry_continue(&(evlist)->entries, evsel)
|
||||
|
||||
/**
|
||||
* __evlist__for_each_reverse - iterate thru all the evsels in reverse order
|
||||
* __evlist__for_each_entry_reverse - iterate thru all the evsels in reverse order
|
||||
* @list: list_head instance to iterate
|
||||
* @evsel: struct evsel iterator
|
||||
*/
|
||||
#define __evlist__for_each_reverse(list, evsel) \
|
||||
#define __evlist__for_each_entry_reverse(list, evsel) \
|
||||
list_for_each_entry_reverse(evsel, list, node)
|
||||
|
||||
/**
|
||||
* evlist__for_each_reverse - iterate thru all the evsels in reverse order
|
||||
* evlist__for_each_entry_reverse - iterate thru all the evsels in reverse order
|
||||
* @evlist: evlist instance to iterate
|
||||
* @evsel: struct evsel iterator
|
||||
*/
|
||||
#define evlist__for_each_reverse(evlist, evsel) \
|
||||
__evlist__for_each_reverse(&(evlist)->entries, evsel)
|
||||
#define evlist__for_each_entry_reverse(evlist, evsel) \
|
||||
__evlist__for_each_entry_reverse(&(evlist)->entries, evsel)
|
||||
|
||||
/**
|
||||
* __evlist__for_each_safe - safely iterate thru all the evsels
|
||||
* __evlist__for_each_entry_safe - safely iterate thru all the evsels
|
||||
* @list: list_head instance to iterate
|
||||
* @tmp: struct evsel temp iterator
|
||||
* @evsel: struct evsel iterator
|
||||
*/
|
||||
#define __evlist__for_each_safe(list, tmp, evsel) \
|
||||
#define __evlist__for_each_entry_safe(list, tmp, evsel) \
|
||||
list_for_each_entry_safe(evsel, tmp, list, node)
|
||||
|
||||
/**
|
||||
* evlist__for_each_safe - safely iterate thru all the evsels
|
||||
* evlist__for_each_entry_safe - safely iterate thru all the evsels
|
||||
* @evlist: evlist instance to iterate
|
||||
* @evsel: struct evsel iterator
|
||||
* @tmp: struct evsel temp iterator
|
||||
*/
|
||||
#define evlist__for_each_safe(evlist, tmp, evsel) \
|
||||
__evlist__for_each_safe(&(evlist)->entries, tmp, evsel)
|
||||
#define evlist__for_each_entry_safe(evlist, tmp, evsel) \
|
||||
__evlist__for_each_entry_safe(&(evlist)->entries, tmp, evsel)
|
||||
|
||||
void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
|
||||
struct perf_evsel *tracking_evsel);
|
||||
|
@ -336,7 +336,7 @@ static int write_event_desc(int fd, struct perf_header *h __maybe_unused,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
ret = do_write(fd, &evsel->attr, sz);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -801,7 +801,7 @@ static int write_group_desc(int fd, struct perf_header *h __maybe_unused,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (perf_evsel__is_group_leader(evsel) &&
|
||||
evsel->nr_members > 1) {
|
||||
const char *name = evsel->group_name ?: "{anon_group}";
|
||||
@ -1425,7 +1425,7 @@ static void print_group_desc(struct perf_header *ph, int fd __maybe_unused,
|
||||
|
||||
session = container_of(ph, struct perf_session, header);
|
||||
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (perf_evsel__is_group_leader(evsel) &&
|
||||
evsel->nr_members > 1) {
|
||||
fprintf(fp, "# group: %s{%s", evsel->group_name ?: "",
|
||||
@ -1703,7 +1703,7 @@ perf_evlist__find_by_index(struct perf_evlist *evlist, int idx)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->idx == idx)
|
||||
return evsel;
|
||||
}
|
||||
@ -2075,7 +2075,7 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused,
|
||||
session->evlist->nr_groups = nr_groups;
|
||||
|
||||
i = nr = 0;
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (evsel->idx == (int) desc[i].leader_idx) {
|
||||
evsel->leader = evsel;
|
||||
/* {anon_group} is a dummy name */
|
||||
@ -2383,7 +2383,7 @@ int perf_session__write_header(struct perf_session *session,
|
||||
|
||||
lseek(fd, sizeof(f_header), SEEK_SET);
|
||||
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
evsel->id_offset = lseek(fd, 0, SEEK_CUR);
|
||||
err = do_write(fd, evsel->id, evsel->ids * sizeof(u64));
|
||||
if (err < 0) {
|
||||
@ -2394,7 +2394,7 @@ int perf_session__write_header(struct perf_session *session,
|
||||
|
||||
attr_offset = lseek(fd, 0, SEEK_CUR);
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
f_attr = (struct perf_file_attr){
|
||||
.attr = evsel->attr,
|
||||
.ids = {
|
||||
@ -2828,7 +2828,7 @@ static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
|
||||
{
|
||||
struct perf_evsel *pos;
|
||||
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
|
||||
perf_evsel__prepare_tracepoint_event(pos, pevent))
|
||||
return -1;
|
||||
@ -3127,7 +3127,7 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,
|
||||
struct perf_evsel *evsel;
|
||||
int err = 0;
|
||||
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
err = perf_event__synthesize_attr(tool, &evsel->attr, evsel->ids,
|
||||
evsel->id, process);
|
||||
if (err) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "cache.h"
|
||||
#include "config.h"
|
||||
#include <subcmd/help.h>
|
||||
#include "../builtin.h"
|
||||
#include "levenshtein.h"
|
||||
|
@ -79,7 +79,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
|
||||
|
||||
len = thread__comm_len(h->thread);
|
||||
if (hists__new_col_len(hists, HISTC_COMM, len))
|
||||
hists__set_col_len(hists, HISTC_THREAD, len + 6);
|
||||
hists__set_col_len(hists, HISTC_THREAD, len + 8);
|
||||
|
||||
if (h->ms.map) {
|
||||
len = dso__name_len(h->ms.map->dso);
|
||||
@ -2199,7 +2199,7 @@ size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp)
|
||||
struct perf_evsel *pos;
|
||||
size_t ret = 0;
|
||||
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos));
|
||||
ret += events_stats__fprintf(&evsel__hists(pos)->stats, fp);
|
||||
}
|
||||
|
@ -422,7 +422,8 @@ static int intel_bts_get_branch_type(struct intel_bts_queue *btsq,
|
||||
}
|
||||
|
||||
static int intel_bts_process_buffer(struct intel_bts_queue *btsq,
|
||||
struct auxtrace_buffer *buffer)
|
||||
struct auxtrace_buffer *buffer,
|
||||
struct thread *thread)
|
||||
{
|
||||
struct branch *branch;
|
||||
size_t sz, bsz = sizeof(struct branch);
|
||||
@ -444,6 +445,12 @@ static int intel_bts_process_buffer(struct intel_bts_queue *btsq,
|
||||
if (!branch->from && !branch->to)
|
||||
continue;
|
||||
intel_bts_get_branch_type(btsq, branch);
|
||||
if (btsq->bts->synth_opts.thread_stack)
|
||||
thread_stack__event(thread, btsq->sample_flags,
|
||||
le64_to_cpu(branch->from),
|
||||
le64_to_cpu(branch->to),
|
||||
btsq->intel_pt_insn.length,
|
||||
buffer->buffer_nr + 1);
|
||||
if (filter && !(filter & btsq->sample_flags))
|
||||
continue;
|
||||
err = intel_bts_synth_branch_sample(btsq, branch);
|
||||
@ -507,12 +514,13 @@ static int intel_bts_process_queue(struct intel_bts_queue *btsq, u64 *timestamp)
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
if (!btsq->bts->synth_opts.callchain && thread &&
|
||||
if (!btsq->bts->synth_opts.callchain &&
|
||||
!btsq->bts->synth_opts.thread_stack && thread &&
|
||||
(!old_buffer || btsq->bts->sampling_mode ||
|
||||
(btsq->bts->snapshot_mode && !buffer->consecutive)))
|
||||
thread_stack__set_trace_nr(thread, buffer->buffer_nr + 1);
|
||||
|
||||
err = intel_bts_process_buffer(btsq, buffer);
|
||||
err = intel_bts_process_buffer(btsq, buffer, thread);
|
||||
|
||||
auxtrace_buffer__drop_data(buffer);
|
||||
|
||||
@ -777,7 +785,7 @@ static int intel_bts_synth_events(struct intel_bts *bts,
|
||||
u64 id;
|
||||
int err;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.type == bts->pmu_type && evsel->ids) {
|
||||
found = true;
|
||||
break;
|
||||
@ -905,10 +913,14 @@ int intel_bts_process_auxtrace_info(union perf_event *event,
|
||||
if (dump_trace)
|
||||
return 0;
|
||||
|
||||
if (session->itrace_synth_opts && session->itrace_synth_opts->set)
|
||||
if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
|
||||
bts->synth_opts = *session->itrace_synth_opts;
|
||||
else
|
||||
} else {
|
||||
itrace_synth_opts__set_default(&bts->synth_opts);
|
||||
if (session->itrace_synth_opts)
|
||||
bts->synth_opts.thread_stack =
|
||||
session->itrace_synth_opts->thread_stack;
|
||||
}
|
||||
|
||||
if (bts->synth_opts.calls)
|
||||
bts->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "auxtrace.h"
|
||||
#include "tsc.h"
|
||||
#include "intel-pt.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "intel-pt-decoder/intel-pt-log.h"
|
||||
#include "intel-pt-decoder/intel-pt-decoder.h"
|
||||
@ -556,7 +557,7 @@ static bool intel_pt_exclude_kernel(struct intel_pt *pt)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(pt->session->evlist, evsel) {
|
||||
evlist__for_each_entry(pt->session->evlist, evsel) {
|
||||
if (intel_pt_get_config(pt, &evsel->attr, NULL) &&
|
||||
!evsel->attr.exclude_kernel)
|
||||
return false;
|
||||
@ -572,7 +573,7 @@ static bool intel_pt_return_compression(struct intel_pt *pt)
|
||||
if (!pt->noretcomp_bit)
|
||||
return true;
|
||||
|
||||
evlist__for_each(pt->session->evlist, evsel) {
|
||||
evlist__for_each_entry(pt->session->evlist, evsel) {
|
||||
if (intel_pt_get_config(pt, &evsel->attr, &config) &&
|
||||
(config & pt->noretcomp_bit))
|
||||
return false;
|
||||
@ -592,7 +593,7 @@ static unsigned int intel_pt_mtc_period(struct intel_pt *pt)
|
||||
for (shift = 0, config = pt->mtc_freq_bits; !(config & 1); shift++)
|
||||
config >>= 1;
|
||||
|
||||
evlist__for_each(pt->session->evlist, evsel) {
|
||||
evlist__for_each_entry(pt->session->evlist, evsel) {
|
||||
if (intel_pt_get_config(pt, &evsel->attr, &config))
|
||||
return (config & pt->mtc_freq_bits) >> shift;
|
||||
}
|
||||
@ -608,7 +609,7 @@ static bool intel_pt_timeless_decoding(struct intel_pt *pt)
|
||||
if (!pt->tsc_bit || !pt->cap_user_time_zero)
|
||||
return true;
|
||||
|
||||
evlist__for_each(pt->session->evlist, evsel) {
|
||||
evlist__for_each_entry(pt->session->evlist, evsel) {
|
||||
if (!(evsel->attr.sample_type & PERF_SAMPLE_TIME))
|
||||
return true;
|
||||
if (intel_pt_get_config(pt, &evsel->attr, &config)) {
|
||||
@ -625,7 +626,7 @@ static bool intel_pt_tracing_kernel(struct intel_pt *pt)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(pt->session->evlist, evsel) {
|
||||
evlist__for_each_entry(pt->session->evlist, evsel) {
|
||||
if (intel_pt_get_config(pt, &evsel->attr, NULL) &&
|
||||
!evsel->attr.exclude_kernel)
|
||||
return true;
|
||||
@ -642,7 +643,7 @@ static bool intel_pt_have_tsc(struct intel_pt *pt)
|
||||
if (!pt->tsc_bit)
|
||||
return false;
|
||||
|
||||
evlist__for_each(pt->session->evlist, evsel) {
|
||||
evlist__for_each_entry(pt->session->evlist, evsel) {
|
||||
if (intel_pt_get_config(pt, &evsel->attr, &config)) {
|
||||
if (config & pt->tsc_bit)
|
||||
have_tsc = true;
|
||||
@ -1233,7 +1234,7 @@ static int intel_pt_sample(struct intel_pt_queue *ptq)
|
||||
if (!(state->type & INTEL_PT_BRANCH))
|
||||
return 0;
|
||||
|
||||
if (pt->synth_opts.callchain)
|
||||
if (pt->synth_opts.callchain || pt->synth_opts.thread_stack)
|
||||
thread_stack__event(ptq->thread, ptq->flags, state->from_ip,
|
||||
state->to_ip, ptq->insn_len,
|
||||
state->trace_nr);
|
||||
@ -1850,7 +1851,7 @@ static int intel_pt_synth_events(struct intel_pt *pt,
|
||||
u64 id;
|
||||
int err;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.type == pt->pmu_type && evsel->ids) {
|
||||
found = true;
|
||||
break;
|
||||
@ -1930,7 +1931,7 @@ static int intel_pt_synth_events(struct intel_pt *pt,
|
||||
pt->sample_transactions = true;
|
||||
pt->transactions_id = id;
|
||||
id += 1;
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->id && evsel->id[0] == pt->transactions_id) {
|
||||
if (evsel->name)
|
||||
zfree(&evsel->name);
|
||||
@ -1968,7 +1969,7 @@ static struct perf_evsel *intel_pt_find_sched_switch(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each_reverse(evlist, evsel) {
|
||||
evlist__for_each_entry_reverse(evlist, evsel) {
|
||||
const char *name = perf_evsel__name(evsel);
|
||||
|
||||
if (!strcmp(name, "sched:sched_switch"))
|
||||
@ -1982,7 +1983,7 @@ static bool intel_pt_find_switch(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.context_switch)
|
||||
return true;
|
||||
}
|
||||
@ -2136,6 +2137,9 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
|
||||
pt->synth_opts.branches = false;
|
||||
pt->synth_opts.callchain = true;
|
||||
}
|
||||
if (session->itrace_synth_opts)
|
||||
pt->synth_opts.thread_stack =
|
||||
session->itrace_synth_opts->thread_stack;
|
||||
}
|
||||
|
||||
if (pt->synth_opts.log)
|
||||
|
@ -57,21 +57,21 @@ static inline struct int_node *intlist__next(struct int_node *in)
|
||||
}
|
||||
|
||||
/**
|
||||
* intlist_for_each - iterate over a intlist
|
||||
* intlist__for_each_entry - iterate over a intlist
|
||||
* @pos: the &struct int_node to use as a loop cursor.
|
||||
* @ilist: the &struct intlist for loop.
|
||||
*/
|
||||
#define intlist__for_each(pos, ilist) \
|
||||
#define intlist__for_each_entry(pos, ilist) \
|
||||
for (pos = intlist__first(ilist); pos; pos = intlist__next(pos))
|
||||
|
||||
/**
|
||||
* intlist_for_each_safe - iterate over a intlist safe against removal of
|
||||
* intlist__for_each_entry_safe - iterate over a intlist safe against removal of
|
||||
* int_node
|
||||
* @pos: the &struct int_node to use as a loop cursor.
|
||||
* @n: another &struct int_node to use as temporary storage.
|
||||
* @ilist: the &struct intlist for loop.
|
||||
*/
|
||||
#define intlist__for_each_safe(pos, n, ilist) \
|
||||
#define intlist__for_each_entry_safe(pos, n, ilist) \
|
||||
for (pos = intlist__first(ilist), n = intlist__next(pos); pos;\
|
||||
pos = n, n = intlist__next(n))
|
||||
#endif /* __PERF_INTLIST_H */
|
||||
|
@ -108,7 +108,7 @@ jit_validate_events(struct perf_session *session)
|
||||
/*
|
||||
* check that all events use CLOCK_MONOTONIC
|
||||
*/
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (evsel->attr.use_clockid == 0 || evsel->attr.clockid != CLOCK_MONOTONIC)
|
||||
return -1;
|
||||
}
|
||||
|
@ -13,7 +13,12 @@
|
||||
|
||||
#define REMOTE_UNWIND_LIBUNWIND
|
||||
|
||||
/* Define arch specific functions & regs for libunwind, should be
|
||||
* defined before including "unwind.h"
|
||||
*/
|
||||
#define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__arm64_reg_id(regnum)
|
||||
#define LIBUNWIND__ARCH_REG_IP PERF_REG_ARM64_PC
|
||||
#define LIBUNWIND__ARCH_REG_SP PERF_REG_ARM64_SP
|
||||
|
||||
#include "unwind.h"
|
||||
#include "debug.h"
|
||||
|
@ -12,7 +12,13 @@
|
||||
*/
|
||||
|
||||
#define REMOTE_UNWIND_LIBUNWIND
|
||||
|
||||
/* Define arch specific functions & regs for libunwind, should be
|
||||
* defined before including "unwind.h"
|
||||
*/
|
||||
#define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__x86_reg_id(regnum)
|
||||
#define LIBUNWIND__ARCH_REG_IP PERF_REG_X86_IP
|
||||
#define LIBUNWIND__ARCH_REG_SP PERF_REG_X86_SP
|
||||
|
||||
#include "unwind.h"
|
||||
#include "debug.h"
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <stdlib.h>
|
||||
#include "debug.h"
|
||||
#include "llvm-utils.h"
|
||||
#include "config.h"
|
||||
|
||||
#define CLANG_BPF_CMD_DEFAULT_TEMPLATE \
|
||||
"$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\
|
||||
|
@ -138,8 +138,10 @@ void machine__exit(struct machine *machine)
|
||||
|
||||
void machine__delete(struct machine *machine)
|
||||
{
|
||||
machine__exit(machine);
|
||||
free(machine);
|
||||
if (machine) {
|
||||
machine__exit(machine);
|
||||
free(machine);
|
||||
}
|
||||
}
|
||||
|
||||
void machines__init(struct machines *machines)
|
||||
|
@ -1396,7 +1396,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
|
||||
if (!add && get_event_modifier(&mod, str, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
__evlist__for_each(list, evsel) {
|
||||
__evlist__for_each_entry(list, evsel) {
|
||||
if (add && get_event_modifier(&mod, str, evsel))
|
||||
return -EINVAL;
|
||||
|
||||
@ -1422,7 +1422,7 @@ int parse_events_name(struct list_head *list, char *name)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
__evlist__for_each(list, evsel) {
|
||||
__evlist__for_each_entry(list, evsel) {
|
||||
if (!evsel->name)
|
||||
evsel->name = strdup(name);
|
||||
}
|
||||
|
@ -102,10 +102,8 @@ out:
|
||||
|
||||
void exit_probe_symbol_maps(void)
|
||||
{
|
||||
if (host_machine) {
|
||||
machine__delete(host_machine);
|
||||
host_machine = NULL;
|
||||
}
|
||||
machine__delete(host_machine);
|
||||
host_machine = NULL;
|
||||
symbol__exit();
|
||||
}
|
||||
|
||||
@ -898,7 +896,7 @@ static int __show_line_range(struct line_range *lr, const char *module,
|
||||
goto end;
|
||||
}
|
||||
|
||||
intlist__for_each(ln, lr->line_list) {
|
||||
intlist__for_each_entry(ln, lr->line_list) {
|
||||
for (; ln->i > l; l++) {
|
||||
ret = show_one_line(fp, l - lr->offset);
|
||||
if (ret < 0)
|
||||
@ -982,7 +980,7 @@ static int show_available_vars_at(struct debuginfo *dinfo,
|
||||
zfree(&vl->point.symbol);
|
||||
nvars = 0;
|
||||
if (vl->vars) {
|
||||
strlist__for_each(node, vl->vars) {
|
||||
strlist__for_each_entry(node, vl->vars) {
|
||||
var = strchr(node->s, '\t') + 1;
|
||||
if (strfilter__compare(_filter, var)) {
|
||||
fprintf(stdout, "\t\t%s\n", node->s);
|
||||
@ -2335,7 +2333,7 @@ static int __show_perf_probe_events(int fd, bool is_kprobe,
|
||||
if (!rawlist)
|
||||
return -ENOMEM;
|
||||
|
||||
strlist__for_each(ent, rawlist) {
|
||||
strlist__for_each_entry(ent, rawlist) {
|
||||
ret = parse_probe_trace_command(ent->s, &tev);
|
||||
if (ret >= 0) {
|
||||
if (!filter_probe_trace_event(&tev, filter))
|
||||
|
@ -178,7 +178,7 @@ static struct strlist *__probe_file__get_namelist(int fd, bool include_group)
|
||||
if (!rawlist)
|
||||
return NULL;
|
||||
sl = strlist__new(NULL, NULL);
|
||||
strlist__for_each(ent, rawlist) {
|
||||
strlist__for_each_entry(ent, rawlist) {
|
||||
ret = parse_probe_trace_command(ent->s, &tev);
|
||||
if (ret < 0)
|
||||
break;
|
||||
@ -281,7 +281,7 @@ int probe_file__get_events(int fd, struct strfilter *filter,
|
||||
if (!namelist)
|
||||
return -ENOENT;
|
||||
|
||||
strlist__for_each(ent, namelist) {
|
||||
strlist__for_each_entry(ent, namelist) {
|
||||
p = strchr(ent->s, ':');
|
||||
if ((p && strfilter__compare(filter, p + 1)) ||
|
||||
strfilter__compare(filter, ent->s)) {
|
||||
@ -299,7 +299,7 @@ int probe_file__del_strlist(int fd, struct strlist *namelist)
|
||||
int ret = 0;
|
||||
struct str_node *ent;
|
||||
|
||||
strlist__for_each(ent, namelist) {
|
||||
strlist__for_each_entry(ent, namelist) {
|
||||
ret = __del_trace_probe_event(fd, ent);
|
||||
if (ret < 0)
|
||||
break;
|
||||
@ -612,7 +612,7 @@ static int probe_cache_entry__write(struct probe_cache_entry *entry, int fd)
|
||||
if (ret < (int)iov[1].iov_len + 2)
|
||||
goto rollback;
|
||||
|
||||
strlist__for_each(snode, entry->tevlist) {
|
||||
strlist__for_each_entry(snode, entry->tevlist) {
|
||||
iov[0].iov_base = (void *)snode->s;
|
||||
iov[0].iov_len = strlen(snode->s);
|
||||
iov[1].iov_base = (void *)"\n"; iov[1].iov_len = 1;
|
||||
|
@ -957,7 +957,7 @@ static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
|
||||
if (i >= pevlist->evlist.nr_entries)
|
||||
return NULL;
|
||||
|
||||
evlist__for_each(&pevlist->evlist, pos) {
|
||||
evlist__for_each_entry(&pevlist->evlist, pos) {
|
||||
if (i-- == 0)
|
||||
break;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ DEFINE_RB_RESORT_RB(threads, strcmp(a->thread->shortname,
|
||||
|
||||
struct rb_node *nd;
|
||||
|
||||
resort_rb__for_each(nd, threads) {
|
||||
resort_rb__for_each_entry(nd, threads) {
|
||||
struct thread *t = threads_entry;
|
||||
printf("%s: %d\n", t->shortname, t->tid);
|
||||
}
|
||||
@ -123,7 +123,7 @@ static void __name##_sorted__init_entry(struct rb_node *nd, \
|
||||
struct __name##_sorted_entry *__name##_entry; \
|
||||
struct __name##_sorted *__name = __name##_sorted__new
|
||||
|
||||
#define resort_rb__for_each(__nd, __name) \
|
||||
#define resort_rb__for_each_entry(__nd, __name) \
|
||||
for (__nd = rb_first(&__name->entries); \
|
||||
__name##_entry = rb_entry(__nd, struct __name##_sorted_entry, \
|
||||
rb_node), __nd; \
|
||||
|
@ -148,7 +148,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
|
||||
|
||||
use_comm_exec = perf_can_comm_exec();
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
perf_evsel__config(evsel, opts, callchain);
|
||||
if (evsel->tracking && use_comm_exec)
|
||||
evsel->attr.comm_exec = 1;
|
||||
@ -161,18 +161,18 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
|
||||
* match the id.
|
||||
*/
|
||||
use_sample_identifier = perf_can_sample_identifier();
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
perf_evsel__set_sample_id(evsel, use_sample_identifier);
|
||||
} else if (evlist->nr_entries > 1) {
|
||||
struct perf_evsel *first = perf_evlist__first(evlist);
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.sample_type == first->attr.sample_type)
|
||||
continue;
|
||||
use_sample_identifier = perf_can_sample_identifier();
|
||||
break;
|
||||
}
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
perf_evsel__set_sample_id(evsel, use_sample_identifier);
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ static bool perf_session__has_comm_exec(struct perf_session *session)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (evsel->attr.comm_exec)
|
||||
return true;
|
||||
}
|
||||
@ -178,6 +178,8 @@ static void perf_session__delete_threads(struct perf_session *session)
|
||||
|
||||
void perf_session__delete(struct perf_session *session)
|
||||
{
|
||||
if (session == NULL)
|
||||
return;
|
||||
auxtrace__free(session);
|
||||
auxtrace_index__free(&session->auxtrace_index);
|
||||
perf_session__destroy_kernel_maps(session);
|
||||
@ -1870,7 +1872,7 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(session->evlist, evsel) {
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (evsel->attr.type == PERF_TYPE_TRACEPOINT)
|
||||
return true;
|
||||
}
|
||||
@ -1952,7 +1954,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
|
||||
{
|
||||
struct perf_evsel *pos;
|
||||
|
||||
evlist__for_each(session->evlist, pos) {
|
||||
evlist__for_each_entry(session->evlist, pos) {
|
||||
if (pos->attr.type == type)
|
||||
return pos;
|
||||
}
|
||||
@ -2107,7 +2109,7 @@ int perf_event__synthesize_id_index(struct perf_tool *tool,
|
||||
max_nr = (UINT16_MAX - sizeof(struct id_index_event)) /
|
||||
sizeof(struct id_index_entry);
|
||||
|
||||
evlist__for_each(evlist, evsel)
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
nr += evsel->ids;
|
||||
|
||||
n = nr > max_nr ? max_nr : nr;
|
||||
@ -2120,7 +2122,7 @@ int perf_event__synthesize_id_index(struct perf_tool *tool,
|
||||
ev->id_index.header.size = sz;
|
||||
ev->id_index.nr = n;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
u32 j;
|
||||
|
||||
for (j = 0; j < evsel->ids; j++) {
|
||||
|
@ -79,8 +79,8 @@ static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
|
||||
{
|
||||
const char *comm = thread__comm_str(he->thread);
|
||||
|
||||
width = max(7U, width) - 6;
|
||||
return repsep_snprintf(bf, size, "%5d:%-*.*s", he->thread->tid,
|
||||
width = max(7U, width) - 8;
|
||||
return repsep_snprintf(bf, size, "%7d:%-*.*s", he->thread->tid,
|
||||
width, width, comm ?: "");
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ static int hist_entry__thread_filter(struct hist_entry *he, int type, const void
|
||||
}
|
||||
|
||||
struct sort_entry sort_thread = {
|
||||
.se_header = " Pid:Command",
|
||||
.se_header = " Pid:Command",
|
||||
.se_cmp = sort__thread_cmp,
|
||||
.se_snprintf = hist_entry__thread_snprintf,
|
||||
.se_filter = hist_entry__thread_filter,
|
||||
@ -2069,7 +2069,7 @@ static struct perf_evsel *find_evsel(struct perf_evlist *evlist, char *event_nam
|
||||
}
|
||||
|
||||
full_name = !!strchr(event_name, ':');
|
||||
evlist__for_each(evlist, pos) {
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
/* case 2 */
|
||||
if (full_name && !strcmp(pos->name, event_name))
|
||||
return pos;
|
||||
@ -2125,7 +2125,7 @@ static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace,
|
||||
int ret;
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
|
||||
continue;
|
||||
|
||||
@ -2143,7 +2143,7 @@ static int add_all_matching_fields(struct perf_evlist *evlist,
|
||||
struct perf_evsel *evsel;
|
||||
struct format_field *field;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
|
||||
continue;
|
||||
|
||||
@ -2456,7 +2456,7 @@ static const char *get_default_sort_order(struct perf_evlist *evlist)
|
||||
if (evlist == NULL)
|
||||
goto out_no_evlist;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
|
||||
use_trace = false;
|
||||
break;
|
||||
|
@ -162,7 +162,7 @@ int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (perf_evsel__alloc_stats(evsel, alloc_raw))
|
||||
goto out_free;
|
||||
}
|
||||
@ -178,7 +178,7 @@ void perf_evlist__free_stats(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
perf_evsel__free_stat_priv(evsel);
|
||||
perf_evsel__free_counts(evsel);
|
||||
perf_evsel__free_prev_raw_counts(evsel);
|
||||
@ -189,7 +189,7 @@ void perf_evlist__reset_stats(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evlist__for_each(evlist, evsel) {
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
perf_evsel__reset_stat_priv(evsel);
|
||||
perf_evsel__reset_counts(evsel);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ static inline struct str_node *strlist__next(struct str_node *sn)
|
||||
* @pos: the &struct str_node to use as a loop cursor.
|
||||
* @slist: the &struct strlist for loop.
|
||||
*/
|
||||
#define strlist__for_each(pos, slist) \
|
||||
#define strlist__for_each_entry(pos, slist) \
|
||||
for (pos = strlist__first(slist); pos; pos = strlist__next(pos))
|
||||
|
||||
/**
|
||||
@ -83,7 +83,7 @@ static inline struct str_node *strlist__next(struct str_node *sn)
|
||||
* @n: another &struct str_node to use as temporary storage.
|
||||
* @slist: the &struct strlist for loop.
|
||||
*/
|
||||
#define strlist__for_each_safe(pos, n, slist) \
|
||||
#define strlist__for_each_entry_safe(pos, n, slist) \
|
||||
for (pos = strlist__first(slist), n = strlist__next(pos); pos;\
|
||||
pos = n, n = strlist__next(n))
|
||||
#endif /* __PERF_STRLIST_H */
|
||||
|
@ -1626,7 +1626,7 @@ static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
|
||||
if (!dirs)
|
||||
return -1;
|
||||
|
||||
strlist__for_each(nd, dirs) {
|
||||
strlist__for_each_entry(nd, dirs) {
|
||||
scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
|
||||
"%s/%s/kallsyms", dir, nd->s);
|
||||
if (!validate_kcore_addresses(kallsyms_filename, map)) {
|
||||
|
@ -616,3 +616,10 @@ int thread_stack__process(struct thread *thread, struct comm *comm,
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
size_t thread_stack__depth(struct thread *thread)
|
||||
{
|
||||
if (!thread->ts)
|
||||
return 0;
|
||||
return thread->ts->cnt;
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ void thread_stack__sample(struct thread *thread, struct ip_callchain *chain,
|
||||
size_t sz, u64 ip);
|
||||
int thread_stack__flush(struct thread *thread);
|
||||
void thread_stack__free(struct thread *thread);
|
||||
size_t thread_stack__depth(struct thread *thread);
|
||||
|
||||
struct call_return_processor *
|
||||
call_return_processor__new(int (*process)(struct call_return *cr, void *data),
|
||||
|
@ -202,7 +202,7 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
|
||||
if (!slist)
|
||||
return NULL;
|
||||
|
||||
strlist__for_each(pos, slist) {
|
||||
strlist__for_each_entry(pos, slist) {
|
||||
pid = strtol(pos->s, &end_ptr, 10);
|
||||
|
||||
if (pid == INT_MIN || pid == INT_MAX ||
|
||||
@ -278,7 +278,7 @@ struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
|
||||
if (!slist)
|
||||
return NULL;
|
||||
|
||||
strlist__for_each(pos, slist) {
|
||||
strlist__for_each_entry(pos, slist) {
|
||||
tid = strtol(pos->s, &end_ptr, 10);
|
||||
|
||||
if (tid == INT_MIN || tid == INT_MAX ||
|
||||
|
@ -462,7 +462,8 @@ static int access_mem(unw_addr_space_t __maybe_unused as,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = perf_reg_value(&start, &ui->sample->user_regs, PERF_REG_SP);
|
||||
ret = perf_reg_value(&start, &ui->sample->user_regs,
|
||||
LIBUNWIND__ARCH_REG_SP);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -621,7 +622,8 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
|
||||
unw_cursor_t c;
|
||||
int ret, i = 0;
|
||||
|
||||
ret = perf_reg_value(&val, &ui->sample->user_regs, PERF_REG_IP);
|
||||
ret = perf_reg_value(&val, &ui->sample->user_regs,
|
||||
LIBUNWIND__ARCH_REG_IP);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -32,6 +32,15 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
|
||||
#ifndef LIBUNWIND__ARCH_REG_ID
|
||||
#define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__arch_reg_id(regnum)
|
||||
#endif
|
||||
|
||||
#ifndef LIBUNWIND__ARCH_REG_SP
|
||||
#define LIBUNWIND__ARCH_REG_SP PERF_REG_SP
|
||||
#endif
|
||||
|
||||
#ifndef LIBUNWIND__ARCH_REG_IP
|
||||
#define LIBUNWIND__ARCH_REG_IP PERF_REG_IP
|
||||
#endif
|
||||
|
||||
int LIBUNWIND__ARCH_REG_ID(int regnum);
|
||||
int unwind__prepare_access(struct thread *thread, struct map *map);
|
||||
void unwind__flush_access(struct thread *thread);
|
||||
|
@ -134,8 +134,6 @@ static struct dso *__machine__addnew_vdso(struct machine *machine, const char *s
|
||||
return dso;
|
||||
}
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
|
||||
static enum dso_type machine__thread_dso_type(struct machine *machine,
|
||||
struct thread *thread)
|
||||
{
|
||||
@ -156,6 +154,8 @@ static enum dso_type machine__thread_dso_type(struct machine *machine,
|
||||
return dso_type;
|
||||
}
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
|
||||
static int vdso__do_copy_compat(FILE *f, int fd)
|
||||
{
|
||||
char buf[4096];
|
||||
@ -283,8 +283,38 @@ static int __machine__findnew_vdso_compat(struct machine *machine,
|
||||
|
||||
#endif
|
||||
|
||||
static struct dso *machine__find_vdso(struct machine *machine,
|
||||
struct thread *thread)
|
||||
{
|
||||
struct dso *dso = NULL;
|
||||
enum dso_type dso_type;
|
||||
|
||||
dso_type = machine__thread_dso_type(machine, thread);
|
||||
switch (dso_type) {
|
||||
case DSO__TYPE_32BIT:
|
||||
dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO32, true);
|
||||
if (!dso) {
|
||||
dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO,
|
||||
true);
|
||||
if (dso && dso_type != dso__type(dso, machine))
|
||||
dso = NULL;
|
||||
}
|
||||
break;
|
||||
case DSO__TYPE_X32BIT:
|
||||
dso = __dsos__find(&machine->dsos, DSO__NAME_VDSOX32, true);
|
||||
break;
|
||||
case DSO__TYPE_64BIT:
|
||||
case DSO__TYPE_UNKNOWN:
|
||||
default:
|
||||
dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO, true);
|
||||
break;
|
||||
}
|
||||
|
||||
return dso;
|
||||
}
|
||||
|
||||
struct dso *machine__findnew_vdso(struct machine *machine,
|
||||
struct thread *thread __maybe_unused)
|
||||
struct thread *thread)
|
||||
{
|
||||
struct vdso_info *vdso_info;
|
||||
struct dso *dso = NULL;
|
||||
@ -297,6 +327,10 @@ struct dso *machine__findnew_vdso(struct machine *machine,
|
||||
if (!vdso_info)
|
||||
goto out_unlock;
|
||||
|
||||
dso = machine__find_vdso(machine, thread);
|
||||
if (dso)
|
||||
goto out_unlock;
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
if (__machine__findnew_vdso_compat(machine, thread, vdso_info, &dso))
|
||||
goto out_unlock;
|
||||
|
Loading…
Reference in New Issue
Block a user