--uid=::
Record events in threads owned by uid. Name or number.
+-G::
+--cgroup::
+ Record events in threads in a cgroup.
+
+ Look for cgroups to set at the /sys/fs/cgroup/perf_event directory, then
+ remove the /sys/fs/cgroup/perf_event/ part and try:
+
+ perf trace -G A -e sched:*switch
+
+ Will set all raw_syscalls:sys_{enter,exit}, pgfault, vfs_getname, etc
+ _and_ sched:sched_switch to the 'A' cgroup, while:
+
+ perf trace -e sched:*switch -G A
+
+ will only set the sched:sched_switch event to the 'A' cgroup, all the
+ other events (raw_syscalls:sys_{enter,exit}, etc are left "without"
+ a cgroup (on the root cgroup, sys wide, etc).
+
+ Multiple cgroups:
+
+ perf trace -G A -e sched:*switch -G B
+
+ the syscall ones go to the 'A' cgroup, the sched:sched_switch goes
+ to the 'B' cgroup.
+
--filter-pids=::
Filter out events for these pids and for 'trace' itself (comma separated list).
#include <traceevent/event-parse.h>
#include <api/fs/tracing_path.h>
#include "builtin.h"
+#include "util/cgroup.h"
#include "util/color.h"
#include "util/debug.h"
#include "util/env.h"
struct perf_evlist *evlist;
struct machine *host;
struct thread *current;
+ struct cgroup *cgroup;
u64 base_time;
FILE *output;
unsigned long nr_events;
trace__sched_stat_runtime))
goto out_error_sched_stat_runtime;
+ /*
+ * If a global cgroup was set, apply it to all the events without an
+ * explicit cgroup. I.e.:
+ *
+ * trace -G A -e sched:*switch
+ *
+ * Will set all raw_syscalls:sys_{enter,exit}, pgfault, vfs_getname, etc
+ * _and_ sched:sched_switch to the 'A' cgroup, while:
+ *
+ * trace -e sched:*switch -G A
+ *
+ * will only set the sched:sched_switch event to the 'A' cgroup, all the
+ * other events (raw_syscalls:sys_{enter,exit}, etc are left "without"
+ * a cgroup (on the root cgroup, sys wide, etc).
+ *
+ * Multiple cgroups:
+ *
+ * trace -G A -e sched:*switch -G B
+ *
+ * the syscall ones go to the 'A' cgroup, the sched:sched_switch goes
+ * to the 'B' cgroup.
+ *
+ * evlist__set_default_cgroup() grabs a reference of the passed cgroup
+ * only for the evsels still without a cgroup, i.e. evsel->cgroup == NULL.
+ */
+ if (trace->cgroup)
+ evlist__set_default_cgroup(trace->evlist, trace->cgroup);
+
err = perf_evlist__create_maps(evlist, &trace->opts.target);
if (err < 0) {
fprintf(trace->output, "Problems parsing the target to trace, check your options!\n");
trace__symbols__exit(trace);
perf_evlist__delete(evlist);
+ cgroup__put(trace->cgroup);
trace->evlist = NULL;
trace->live = false;
return err;
return err;
}
+static int trace__parse_cgroups(const struct option *opt, const char *str, int unset)
+{
+ struct trace *trace = opt->value;
+
+ if (!list_empty(&trace->evlist->entries))
+ return parse_cgroups(opt, str, unset);
+
+ trace->cgroup = evlist__findnew_cgroup(trace->evlist, str);
+
+ return 0;
+}
+
int cmd_trace(int argc, const char **argv)
{
const char *trace_usage[] = {
"print the PERF_RECORD_SAMPLE PERF_SAMPLE_ info, for debugging"),
OPT_UINTEGER(0, "proc-map-timeout", &trace.opts.proc_map_timeout,
"per thread proc mmap processing timeout in ms"),
+ OPT_CALLBACK('G', "cgroup", &trace, "name", "monitor event in cgroup name only",
+ trace__parse_cgroups),
OPT_UINTEGER('D', "delay", &trace.opts.initial_delay,
"ms to wait before starting measurement after program "
"start"),
argc = parse_options_subcommand(argc, argv, trace_options, trace_subcommands,
trace_usage, PARSE_OPT_STOP_AT_NON_OPTION);
+ if ((nr_cgroups || trace.cgroup) && !trace.opts.target.system_wide) {
+ usage_with_options_msg(trace_usage, trace_options,
+ "cgroup monitoring only available in system-wide mode");
+ }
+
err = bpf__setup_stdout(trace.evlist);
if (err) {
bpf__strerror_setup_stdout(trace.evlist, err, bf, sizeof(bf));