Skip to content

Commit

Permalink
perf evlist: Store pointer to the cpu and thread maps
Browse files Browse the repository at this point in the history
So that we don't have to pass it around to the several methods that
needs it, simplifying usage.

There is one case where we don't have the thread/cpu map in advance,
which is in the parsing routines used by top, stat, record, that we have
to wait till all options are parsed to know if a cpu or thread list was
passed to then create those maps.

For that case consolidate the cpu and thread map creation via
perf_evlist__create_maps() out of the code in top and record, while also
providing a perf_evlist__set_maps() for cases where multiple evlists
share maps or for when maps that represent CPU sockets, for instance,
get crafted out of topology information or subsets of threads in a
particular application are to be monitored, providing more granularity
in specifying which cpus and threads to monitor.

Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Cc: Tom Zanussi <[email protected]>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
acmel committed Jan 31, 2011
1 parent f8a9530 commit 7e2ed09
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 119 deletions.
44 changes: 16 additions & 28 deletions tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ static u64 user_interval = ULLONG_MAX;
static u64 default_interval = 0;
static u64 sample_type;

static struct cpu_map *cpus;
static unsigned int page_size;
static unsigned int mmap_pages = 128;
static unsigned int user_freq = UINT_MAX;
Expand All @@ -58,7 +57,6 @@ static bool sample_id_all_avail = true;
static bool system_wide = false;
static pid_t target_pid = -1;
static pid_t target_tid = -1;
static struct thread_map *threads;
static pid_t child_pid = -1;
static bool no_inherit = false;
static enum write_mode_t write_mode = WRITE_FORCE;
Expand Down Expand Up @@ -189,7 +187,7 @@ static void create_counter(struct perf_evsel *evsel, int cpu)
int thread_index;
int ret;

for (thread_index = 0; thread_index < threads->nr; thread_index++) {
for (thread_index = 0; thread_index < evsel_list->threads->nr; thread_index++) {
h_attr = get_header_attr(attr, evsel->idx);
if (h_attr == NULL)
die("nomem\n");
Expand Down Expand Up @@ -317,7 +315,8 @@ static void open_counters(struct perf_evlist *evlist)
retry_sample_id:
attr->sample_id_all = sample_id_all_avail ? 1 : 0;
try_again:
if (perf_evsel__open(pos, cpus, threads, group, !no_inherit) < 0) {
if (perf_evsel__open(pos, evlist->cpus, evlist->threads, group,
!no_inherit) < 0) {
int err = errno;

if (err == EPERM || err == EACCES)
Expand Down Expand Up @@ -368,10 +367,10 @@ static void open_counters(struct perf_evlist *evlist)
}
}

if (perf_evlist__mmap(evlist, cpus, threads, mmap_pages, false) < 0)
if (perf_evlist__mmap(evlist, mmap_pages, false) < 0)
die("failed to mmap with %d (%s)\n", errno, strerror(errno));

for (cpu = 0; cpu < cpus->nr; ++cpu) {
for (cpu = 0; cpu < evsel_list->cpus->nr; ++cpu) {
list_for_each_entry(pos, &evlist->entries, node)
create_counter(pos, cpu);
}
Expand Down Expand Up @@ -450,7 +449,7 @@ static void mmap_read_all(void)
{
int i;

for (i = 0; i < cpus->nr; i++) {
for (i = 0; i < evsel_list->cpus->nr; i++) {
if (evsel_list->mmap[i].base)
mmap_read(&evsel_list->mmap[i]);
}
Expand Down Expand Up @@ -584,7 +583,7 @@ static int __cmd_record(int argc, const char **argv)
}

if (!system_wide && target_tid == -1 && target_pid == -1)
threads->map[0] = child_pid;
evsel_list->threads->map[0] = child_pid;

close(child_ready_pipe[1]);
close(go_pipe[0]);
Expand Down Expand Up @@ -718,12 +717,12 @@ static int __cmd_record(int argc, const char **argv)
}

if (done) {
for (i = 0; i < cpus->nr; i++) {
for (i = 0; i < evsel_list->cpus->nr; i++) {
struct perf_evsel *pos;

list_for_each_entry(pos, &evsel_list->entries, node) {
for (thread = 0;
thread < threads->nr;
thread < evsel_list->threads->nr;
thread++)
ioctl(FD(pos, i, thread),
PERF_EVENT_IOC_DISABLE);
Expand Down Expand Up @@ -816,7 +815,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
int err = -ENOMEM;
struct perf_evsel *pos;

evsel_list = perf_evlist__new();
evsel_list = perf_evlist__new(NULL, NULL);
if (evsel_list == NULL)
return -ENOMEM;

Expand Down Expand Up @@ -850,28 +849,19 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
if (target_pid != -1)
target_tid = target_pid;

threads = thread_map__new(target_pid, target_tid);
if (threads == NULL) {
pr_err("Problems finding threads of monitor\n");
usage_with_options(record_usage, record_options);
}

if (target_tid != -1)
cpus = cpu_map__dummy_new();
else
cpus = cpu_map__new(cpu_list);

if (cpus == NULL)
if (perf_evlist__create_maps(evsel_list, target_pid,
target_tid, cpu_list) < 0)
usage_with_options(record_usage, record_options);

list_for_each_entry(pos, &evsel_list->entries, node) {
if (perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
if (perf_evsel__alloc_fd(pos, evsel_list->cpus->nr,
evsel_list->threads->nr) < 0)
goto out_free_fd;
if (perf_header__push_event(pos->attr.config, event_name(pos)))
goto out_free_fd;
}

if (perf_evlist__alloc_pollfd(evsel_list, cpus->nr, threads->nr) < 0)
if (perf_evlist__alloc_pollfd(evsel_list) < 0)
goto out_free_fd;

if (user_interval != ULLONG_MAX)
Expand All @@ -893,10 +883,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
}

err = __cmd_record(argc, argv);

out_free_fd:
thread_map__delete(threads);
threads = NULL;
perf_evlist__delete_maps(evsel_list);
out_symbol_exit:
symbol__exit();
return err;
Expand Down
45 changes: 22 additions & 23 deletions tools/perf/builtin-stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ static struct perf_event_attr default_attrs[] = {
struct perf_evlist *evsel_list;

static bool system_wide = false;
static struct cpu_map *cpus;
static int run_idx = 0;

static int run_count = 1;
Expand All @@ -85,7 +84,6 @@ static bool scale = true;
static bool no_aggr = false;
static pid_t target_pid = -1;
static pid_t target_tid = -1;
static struct thread_map *threads;
static pid_t child_pid = -1;
static bool null_run = false;
static bool big_num = true;
Expand Down Expand Up @@ -170,15 +168,15 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
PERF_FORMAT_TOTAL_TIME_RUNNING;

if (system_wide)
return perf_evsel__open_per_cpu(evsel, cpus, false, false);
return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, false, false);

attr->inherit = !no_inherit;
if (target_pid == -1 && target_tid == -1) {
attr->disabled = 1;
attr->enable_on_exec = 1;
}

return perf_evsel__open_per_thread(evsel, threads, false, false);
return perf_evsel__open_per_thread(evsel, evsel_list->threads, false, false);
}

/*
Expand All @@ -203,7 +201,8 @@ static int read_counter_aggr(struct perf_evsel *counter)
u64 *count = counter->counts->aggr.values;
int i;

if (__perf_evsel__read(counter, cpus->nr, threads->nr, scale) < 0)
if (__perf_evsel__read(counter, evsel_list->cpus->nr,
evsel_list->threads->nr, scale) < 0)
return -1;

for (i = 0; i < 3; i++)
Expand Down Expand Up @@ -236,7 +235,7 @@ static int read_counter(struct perf_evsel *counter)
u64 *count;
int cpu;

for (cpu = 0; cpu < cpus->nr; cpu++) {
for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) {
if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0)
return -1;

Expand Down Expand Up @@ -301,7 +300,7 @@ static int run_perf_stat(int argc __used, const char **argv)
}

if (target_tid == -1 && target_pid == -1 && !system_wide)
threads->map[0] = child_pid;
evsel_list->threads->map[0] = child_pid;

/*
* Wait for the child to be ready to exec.
Expand Down Expand Up @@ -353,12 +352,13 @@ static int run_perf_stat(int argc __used, const char **argv)
if (no_aggr) {
list_for_each_entry(counter, &evsel_list->entries, node) {
read_counter(counter);
perf_evsel__close_fd(counter, cpus->nr, 1);
perf_evsel__close_fd(counter, evsel_list->cpus->nr, 1);
}
} else {
list_for_each_entry(counter, &evsel_list->entries, node) {
read_counter_aggr(counter);
perf_evsel__close_fd(counter, cpus->nr, threads->nr);
perf_evsel__close_fd(counter, evsel_list->cpus->nr,
evsel_list->threads->nr);
}
}

Expand Down Expand Up @@ -386,7 +386,7 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
if (no_aggr)
sprintf(cpustr, "CPU%*d%s",
csv_output ? 0 : -4,
cpus->map[cpu], csv_sep);
evsel_list->cpus->map[cpu], csv_sep);

fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(evsel));

Expand Down Expand Up @@ -414,7 +414,7 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
if (no_aggr)
sprintf(cpustr, "CPU%*d%s",
csv_output ? 0 : -4,
cpus->map[cpu], csv_sep);
evsel_list->cpus->map[cpu], csv_sep);
else
cpu = 0;

Expand Down Expand Up @@ -500,14 +500,14 @@ static void print_counter(struct perf_evsel *counter)
u64 ena, run, val;
int cpu;

for (cpu = 0; cpu < cpus->nr; cpu++) {
for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) {
val = counter->counts->cpu[cpu].val;
ena = counter->counts->cpu[cpu].ena;
run = counter->counts->cpu[cpu].run;
if (run == 0 || ena == 0) {
fprintf(stderr, "CPU%*d%s%*s%s%-24s",
csv_output ? 0 : -4,
cpus->map[cpu], csv_sep,
evsel_list->cpus->map[cpu], csv_sep,
csv_output ? 0 : 18,
"<not counted>", csv_sep,
event_name(counter));
Expand Down Expand Up @@ -652,7 +652,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)

setlocale(LC_ALL, "");

evsel_list = perf_evlist__new();
evsel_list = perf_evlist__new(NULL, NULL);
if (evsel_list == NULL)
return -ENOMEM;

Expand Down Expand Up @@ -701,27 +701,27 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
if (target_pid != -1)
target_tid = target_pid;

threads = thread_map__new(target_pid, target_tid);
if (threads == NULL) {
evsel_list->threads = thread_map__new(target_pid, target_tid);
if (evsel_list->threads == NULL) {
pr_err("Problems finding threads of monitor\n");
usage_with_options(stat_usage, options);
}

if (system_wide)
cpus = cpu_map__new(cpu_list);
evsel_list->cpus = cpu_map__new(cpu_list);
else
cpus = cpu_map__dummy_new();
evsel_list->cpus = cpu_map__dummy_new();

if (cpus == NULL) {
if (evsel_list->cpus == NULL) {
perror("failed to parse CPUs map");
usage_with_options(stat_usage, options);
return -1;
}

list_for_each_entry(pos, &evsel_list->entries, node) {
if (perf_evsel__alloc_stat_priv(pos) < 0 ||
perf_evsel__alloc_counts(pos, cpus->nr) < 0 ||
perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
perf_evsel__alloc_counts(pos, evsel_list->cpus->nr) < 0 ||
perf_evsel__alloc_fd(pos, evsel_list->cpus->nr, evsel_list->threads->nr) < 0)
goto out_free_fd;
}

Expand Down Expand Up @@ -750,7 +750,6 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
perf_evsel__free_stat_priv(pos);
perf_evlist__delete(evsel_list);
out:
thread_map__delete(threads);
threads = NULL;
perf_evlist__delete_maps(evsel_list);
return status;
}
6 changes: 3 additions & 3 deletions tools/perf/builtin-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ static int test__basic_mmap(void)
goto out_free_cpus;
}

evlist = perf_evlist__new();
evlist = perf_evlist__new(cpus, threads);
if (evlist == NULL) {
pr_debug("perf_evlist__new\n");
goto out_free_cpus;
Expand Down Expand Up @@ -537,7 +537,7 @@ static int test__basic_mmap(void)
}
}

if (perf_evlist__mmap(evlist, cpus, threads, 128, true) < 0) {
if (perf_evlist__mmap(evlist, 128, true) < 0) {
pr_debug("failed to mmap events: %d (%s)\n", errno,
strerror(errno));
goto out_close_fd;
Expand Down Expand Up @@ -579,7 +579,7 @@ static int test__basic_mmap(void)

err = 0;
out_munmap:
perf_evlist__munmap(evlist, 1);
perf_evlist__munmap(evlist);
out_close_fd:
for (i = 0; i < nsyscalls; ++i)
perf_evsel__close_fd(evsels[i], 1, threads->nr);
Expand Down
Loading

0 comments on commit 7e2ed09

Please sign in to comment.