perf record: Make per-cpu mmaps the default.
This affects the -p, -t and -u options that previously defaulted to per-thread mmaps. Consequently add an option to select per-thread mmaps to support the old behaviour. Note that per-thread can be used with a workload-only (i.e. none of -p, -t, -u, -a or -C is selected) to get a per-thread mmap with no inheritance. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Acked-by: Ingo Molnar <mingo@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/5286271D.3020808@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
e944d3d7d1
commit
3aa5939d71
|
@ -201,11 +201,11 @@ abort events and some memory events in precise mode on modern Intel CPUs.
|
||||||
--transaction::
|
--transaction::
|
||||||
Record transaction flags for transaction related events.
|
Record transaction flags for transaction related events.
|
||||||
|
|
||||||
--force-per-cpu::
|
--per-thread::
|
||||||
Force the use of per-cpu mmaps. By default, when tasks are specified (i.e. -p,
|
Use per-thread mmaps. By default per-cpu mmaps are created. This option
|
||||||
-t or -u options) per-thread mmaps are created. This option overrides that and
|
overrides that and uses per-thread mmaps. A side-effect of that is that
|
||||||
forces per-cpu mmaps. A side-effect of that is that inheritance is
|
inheritance is automatically disabled. --per-thread is ignored with a warning
|
||||||
automatically enabled. Add the -i option also to disable inheritance.
|
if combined with -a or -C options.
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -800,6 +800,7 @@ static struct perf_record record = {
|
||||||
.freq = 4000,
|
.freq = 4000,
|
||||||
.target = {
|
.target = {
|
||||||
.uses_mmap = true,
|
.uses_mmap = true,
|
||||||
|
.default_per_cpu = true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -888,8 +889,8 @@ const struct option record_options[] = {
|
||||||
"sample by weight (on special events only)"),
|
"sample by weight (on special events only)"),
|
||||||
OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
|
OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
|
||||||
"sample transaction flags (special events only)"),
|
"sample transaction flags (special events only)"),
|
||||||
OPT_BOOLEAN(0, "force-per-cpu", &record.opts.target.force_per_cpu,
|
OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
|
||||||
"force the use of per-cpu mmaps"),
|
"use per-thread mmaps"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,5 +3,5 @@ command = record
|
||||||
args = -i kill >/dev/null 2>&1
|
args = -i kill >/dev/null 2>&1
|
||||||
|
|
||||||
[event:base-record]
|
[event:base-record]
|
||||||
sample_type=259
|
sample_type=263
|
||||||
inherit=0
|
inherit=0
|
||||||
|
|
|
@ -819,8 +819,10 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
|
||||||
if (evlist->threads == NULL)
|
if (evlist->threads == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (target->force_per_cpu)
|
if (target->default_per_cpu)
|
||||||
evlist->cpus = cpu_map__new(target->cpu_list);
|
evlist->cpus = target->per_thread ?
|
||||||
|
cpu_map__dummy_new() :
|
||||||
|
cpu_map__new(target->cpu_list);
|
||||||
else if (target__has_task(target))
|
else if (target__has_task(target))
|
||||||
evlist->cpus = cpu_map__dummy_new();
|
evlist->cpus = cpu_map__dummy_new();
|
||||||
else if (!target__has_cpu(target) && !target->uses_mmap)
|
else if (!target__has_cpu(target) && !target->uses_mmap)
|
||||||
|
|
|
@ -574,6 +574,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
|
||||||
struct perf_evsel *leader = evsel->leader;
|
struct perf_evsel *leader = evsel->leader;
|
||||||
struct perf_event_attr *attr = &evsel->attr;
|
struct perf_event_attr *attr = &evsel->attr;
|
||||||
int track = !evsel->idx; /* only the first counter needs these */
|
int track = !evsel->idx; /* only the first counter needs these */
|
||||||
|
bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread;
|
||||||
|
|
||||||
attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1;
|
attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1;
|
||||||
attr->inherit = !opts->no_inherit;
|
attr->inherit = !opts->no_inherit;
|
||||||
|
@ -647,7 +648,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target__has_cpu(&opts->target) || opts->target.force_per_cpu)
|
if (target__has_cpu(&opts->target))
|
||||||
perf_evsel__set_sample_bit(evsel, CPU);
|
perf_evsel__set_sample_bit(evsel, CPU);
|
||||||
|
|
||||||
if (opts->period)
|
if (opts->period)
|
||||||
|
@ -655,7 +656,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
|
||||||
|
|
||||||
if (!perf_missing_features.sample_id_all &&
|
if (!perf_missing_features.sample_id_all &&
|
||||||
(opts->sample_time || !opts->no_inherit ||
|
(opts->sample_time || !opts->no_inherit ||
|
||||||
target__has_cpu(&opts->target) || opts->target.force_per_cpu))
|
target__has_cpu(&opts->target) || per_cpu))
|
||||||
perf_evsel__set_sample_bit(evsel, TIME);
|
perf_evsel__set_sample_bit(evsel, TIME);
|
||||||
|
|
||||||
if (opts->raw_samples) {
|
if (opts->raw_samples) {
|
||||||
|
|
|
@ -55,6 +55,13 @@ enum target_errno target__validate(struct target *target)
|
||||||
ret = TARGET_ERRNO__UID_OVERRIDE_SYSTEM;
|
ret = TARGET_ERRNO__UID_OVERRIDE_SYSTEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* THREAD and SYSTEM/CPU are mutually exclusive */
|
||||||
|
if (target->per_thread && (target->system_wide || target->cpu_list)) {
|
||||||
|
target->per_thread = false;
|
||||||
|
if (ret == TARGET_ERRNO__SUCCESS)
|
||||||
|
ret = TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +107,7 @@ static const char *target__error_str[] = {
|
||||||
"UID switch overriding CPU",
|
"UID switch overriding CPU",
|
||||||
"PID/TID switch overriding SYSTEM",
|
"PID/TID switch overriding SYSTEM",
|
||||||
"UID switch overriding SYSTEM",
|
"UID switch overriding SYSTEM",
|
||||||
|
"SYSTEM/CPU switch overriding PER-THREAD",
|
||||||
"Invalid User: %s",
|
"Invalid User: %s",
|
||||||
"Problems obtaining information for user %s",
|
"Problems obtaining information for user %s",
|
||||||
};
|
};
|
||||||
|
@ -131,7 +139,8 @@ int target__strerror(struct target *target, int errnum,
|
||||||
msg = target__error_str[idx];
|
msg = target__error_str[idx];
|
||||||
|
|
||||||
switch (errnum) {
|
switch (errnum) {
|
||||||
case TARGET_ERRNO__PID_OVERRIDE_CPU ... TARGET_ERRNO__UID_OVERRIDE_SYSTEM:
|
case TARGET_ERRNO__PID_OVERRIDE_CPU ...
|
||||||
|
TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD:
|
||||||
snprintf(buf, buflen, "%s", msg);
|
snprintf(buf, buflen, "%s", msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,8 @@ struct target {
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
bool system_wide;
|
bool system_wide;
|
||||||
bool uses_mmap;
|
bool uses_mmap;
|
||||||
bool force_per_cpu;
|
bool default_per_cpu;
|
||||||
|
bool per_thread;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum target_errno {
|
enum target_errno {
|
||||||
|
@ -33,6 +34,7 @@ enum target_errno {
|
||||||
TARGET_ERRNO__UID_OVERRIDE_CPU,
|
TARGET_ERRNO__UID_OVERRIDE_CPU,
|
||||||
TARGET_ERRNO__PID_OVERRIDE_SYSTEM,
|
TARGET_ERRNO__PID_OVERRIDE_SYSTEM,
|
||||||
TARGET_ERRNO__UID_OVERRIDE_SYSTEM,
|
TARGET_ERRNO__UID_OVERRIDE_SYSTEM,
|
||||||
|
TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD,
|
||||||
|
|
||||||
/* for target__parse_uid() */
|
/* for target__parse_uid() */
|
||||||
TARGET_ERRNO__INVALID_UID,
|
TARGET_ERRNO__INVALID_UID,
|
||||||
|
|
Loading…
Reference in New Issue