Browse Source

perf record: Add option --switch-events to select PERF_RECORD_SWITCH events

Add an option to select PERF_RECORD_SWITCH events.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Jiri Olsa <jolsa@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1437471846-26995-4-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Adrian Hunter 10 years ago
parent
commit
b757bb0913

+ 4 - 0
tools/perf/Documentation/perf-record.txt

@@ -293,6 +293,10 @@ When processing pre-existing threads /proc/XXX/mmap, it may take a long time,
 because the file may be huge. A time out is needed in such cases.
 because the file may be huge. A time out is needed in such cases.
 This option sets the time out limit. The default value is 500 ms.
 This option sets the time out limit. The default value is 500 ms.
 
 
+--switch-events::
+Record context switch events i.e. events of type PERF_RECORD_SWITCH or
+PERF_RECORD_SWITCH_CPU_WIDE.
+
 SEE ALSO
 SEE ALSO
 --------
 --------
 linkperf:perf-stat[1], linkperf:perf-list[1]
 linkperf:perf-stat[1], linkperf:perf-list[1]

+ 7 - 0
tools/perf/builtin-record.c

@@ -1075,6 +1075,8 @@ struct option __record_options[] = {
 			  "opts", "AUX area tracing Snapshot Mode", ""),
 			  "opts", "AUX area tracing Snapshot Mode", ""),
 	OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
 	OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
 			"per thread proc mmap processing timeout in ms"),
 			"per thread proc mmap processing timeout in ms"),
+	OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
+		    "Record context switch events"),
 	OPT_END()
 	OPT_END()
 };
 };
 
 
@@ -1102,6 +1104,11 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
 			  " system-wide mode\n");
 			  " system-wide mode\n");
 		usage_with_options(record_usage, record_options);
 		usage_with_options(record_usage, record_options);
 	}
 	}
+	if (rec->opts.record_switch_events &&
+	    !perf_can_record_switch_events()) {
+		ui__error("kernel does not support recording context switch events (--switch-events option)\n");
+		usage_with_options(record_usage, record_options);
+	}
 
 
 	if (!rec->itr) {
 	if (!rec->itr) {
 		rec->itr = auxtrace_record__init(rec->evlist, &err);
 		rec->itr = auxtrace_record__init(rec->evlist, &err);

+ 1 - 0
tools/perf/perf.h

@@ -57,6 +57,7 @@ struct record_opts {
 	bool	     running_time;
 	bool	     running_time;
 	bool	     full_auxtrace;
 	bool	     full_auxtrace;
 	bool	     auxtrace_snapshot_mode;
 	bool	     auxtrace_snapshot_mode;
+	bool	     record_switch_events;
 	unsigned int freq;
 	unsigned int freq;
 	unsigned int mmap_pages;
 	unsigned int mmap_pages;
 	unsigned int auxtrace_mmap_pages;
 	unsigned int auxtrace_mmap_pages;

+ 1 - 0
tools/perf/util/evlist.h

@@ -114,6 +114,7 @@ void perf_evlist__close(struct perf_evlist *evlist);
 
 
 void perf_evlist__set_id_pos(struct perf_evlist *evlist);
 void perf_evlist__set_id_pos(struct perf_evlist *evlist);
 bool perf_can_sample_identifier(void);
 bool perf_can_sample_identifier(void);
+bool perf_can_record_switch_events(void);
 void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts);
 void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts);
 int record_opts__config(struct record_opts *opts);
 int record_opts__config(struct record_opts *opts);
 
 

+ 3 - 0
tools/perf/util/evsel.c

@@ -738,6 +738,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 	attr->mmap2 = track && !perf_missing_features.mmap2;
 	attr->mmap2 = track && !perf_missing_features.mmap2;
 	attr->comm  = track;
 	attr->comm  = track;
 
 
+	if (opts->record_switch_events)
+		attr->context_switch = track;
+
 	if (opts->sample_transaction)
 	if (opts->sample_transaction)
 		perf_evsel__set_sample_bit(evsel, TRANSACTION);
 		perf_evsel__set_sample_bit(evsel, TRANSACTION);
 
 

+ 10 - 0
tools/perf/util/record.c

@@ -85,6 +85,11 @@ static void perf_probe_comm_exec(struct perf_evsel *evsel)
 	evsel->attr.comm_exec = 1;
 	evsel->attr.comm_exec = 1;
 }
 }
 
 
+static void perf_probe_context_switch(struct perf_evsel *evsel)
+{
+	evsel->attr.context_switch = 1;
+}
+
 bool perf_can_sample_identifier(void)
 bool perf_can_sample_identifier(void)
 {
 {
 	return perf_probe_api(perf_probe_sample_identifier);
 	return perf_probe_api(perf_probe_sample_identifier);
@@ -95,6 +100,11 @@ static bool perf_can_comm_exec(void)
 	return perf_probe_api(perf_probe_comm_exec);
 	return perf_probe_api(perf_probe_comm_exec);
 }
 }
 
 
+bool perf_can_record_switch_events(void)
+{
+	return perf_probe_api(perf_probe_context_switch);
+}
+
 void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
 void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
 {
 {
 	struct perf_evsel *evsel;
 	struct perf_evsel *evsel;