Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c45c6ea2 authored by Stephane Eranian's avatar Stephane Eranian Committed by Arnaldo Carvalho de Melo
Browse files

perf tools: Add the ability to specify list of cpus to monitor



This patch adds a -C option to stat, record, top to designate a list of CPUs to
monitor. CPUs can be specified as a comma-separated list or ranges, no space
allowed.

Examples:
$ perf record -a -C0-1,4-7 sleep 1
$ perf top -C0-4
$ perf stat -a -C1,2,3,4 sleep 1

With perf record in per-thread mode with inherit mode on, samples are collected
only when the thread runs on the designated CPUs.

The -C option does not turn on system-wide mode automatically.

Cc: David S. Miller <davem@davemloft.net>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <4bff9496.d345d80a.41fe.7b00@mx.google.com>
Signed-off-by: default avatarStephane Eranian <eranian@google.com>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 761844b9
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -103,6 +103,13 @@ OPTIONS
--raw-samples::
Collect raw sample records from all opened counters (default for tracepoint counters).

-C::
--cpu::
Collect samples only on the list of cpus provided. Multiple CPUs can be provided as a
comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
In per-thread mode with inheritance mode on (default), samples are captured only when
the thread executes on the designated CPUs. Default is to monitor all CPUs.

SEE ALSO
--------
linkperf:perf-stat[1], linkperf:perf-list[1]
+7 −0
Original line number Diff line number Diff line
@@ -46,6 +46,13 @@ OPTIONS
-B::
        print large numbers with thousands' separators according to locale

-C::
--cpu=::
Count only on the list of cpus provided. Multiple CPUs can be provided as a
comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
In per-thread mode, this option is ignored. The -a option is still necessary
to activate system-wide monitoring. Default is to count on all CPUs.

EXAMPLES
--------

+5 −3
Original line number Diff line number Diff line
@@ -25,9 +25,11 @@ OPTIONS
--count=<count>::
	Event period to sample.

-C <cpu>::
--CPU=<cpu>::
	CPU to profile.
-C <cpu-list>::
--cpu=<cpu>::
Monitor only on the list of cpus provided. Multiple CPUs can be provided as a
comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
Default is to monitor all CPUS.

-d <seconds>::
--delay=<seconds>::
+14 −9
Original line number Diff line number Diff line
@@ -49,7 +49,6 @@ static int group = 0;
static int			realtime_prio			=      0;
static bool			raw_samples			=  false;
static bool			system_wide			=  false;
static int			profile_cpu			=     -1;
static pid_t			target_pid			=     -1;
static pid_t			target_tid			=     -1;
static pid_t			*all_tids			=      NULL;
@@ -74,6 +73,7 @@ static int file_new = 1;
static off_t			post_processing_offset;

static struct perf_session	*session;
static const char		*cpu_list;

struct mmap_data {
	int			counter;
@@ -300,7 +300,7 @@ static void create_counter(int counter, int cpu)
				die("Permission error - are you root?\n"
					"\t Consider tweaking"
					" /proc/sys/kernel/perf_event_paranoid.\n");
			else if (err ==  ENODEV && profile_cpu != -1) {
			else if (err ==  ENODEV && cpu_list) {
				die("No such device - did you specify"
					" an out-of-range profile CPU?\n");
			}
@@ -622,10 +622,15 @@ static int __cmd_record(int argc, const char **argv)
		close(child_ready_pipe[0]);
	}

	if ((!system_wide && no_inherit) || profile_cpu != -1) {
		open_counters(profile_cpu);
	nr_cpus = read_cpu_map(cpu_list);
	if (nr_cpus < 1) {
		perror("failed to collect number of CPUs\n");
		return -1;
	}

	if (!system_wide && no_inherit && !cpu_list) {
		open_counters(-1);
	} else {
		nr_cpus = read_cpu_map();
		for (i = 0; i < nr_cpus; i++)
			open_counters(cpumap[i]);
	}
@@ -704,7 +709,7 @@ static int __cmd_record(int argc, const char **argv)
	if (perf_guest)
		perf_session__process_machines(session, event__synthesize_guest_os);

	if (!system_wide && profile_cpu == -1)
	if (!system_wide && cpu_list)
		event__synthesize_thread(target_tid, process_synthesized_event,
					 session);
	else
@@ -794,8 +799,8 @@ static const struct option options[] = {
			    "system-wide collection from all CPUs"),
	OPT_BOOLEAN('A', "append", &append_file,
			    "append to the output file to do incremental profiling"),
	OPT_INTEGER('C', "profile_cpu", &profile_cpu,
			    "CPU to profile on"),
	OPT_STRING('C', "cpu", &cpu_list, "cpu",
		    "list of cpus to monitor"),
	OPT_BOOLEAN('f', "force", &force,
			"overwrite existing data file (deprecated)"),
	OPT_U64('c', "count", &user_interval, "event period to sample"),
@@ -825,7 +830,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
	argc = parse_options(argc, argv, options, record_usage,
			    PARSE_OPT_STOP_AT_NON_OPTION);
	if (!argc && target_pid == -1 && target_tid == -1 &&
		!system_wide && profile_cpu == -1)
		!system_wide && !cpu_list)
		usage_with_options(record_usage, options);

	if (force && append_file) {
+10 −4
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ static struct perf_event_attr default_attrs[] = {
};

static bool			system_wide			=  false;
static unsigned int		nr_cpus				=  0;
static int			nr_cpus				=  0;
static int			run_idx				=  0;

static int			run_count			=  1;
@@ -82,6 +82,7 @@ static int thread_num = 0;
static pid_t			child_pid			= -1;
static bool			null_run			=  false;
static bool			big_num				=  false;
static const char		*cpu_list;


static int			*fd[MAX_NR_CPUS][MAX_COUNTERS];
@@ -158,7 +159,7 @@ static int create_perf_stat_counter(int counter)
				    PERF_FORMAT_TOTAL_TIME_RUNNING;

	if (system_wide) {
		unsigned int cpu;
		int cpu;

		for (cpu = 0; cpu < nr_cpus; cpu++) {
			fd[cpu][counter][0] = sys_perf_event_open(attr,
@@ -208,7 +209,7 @@ static inline int nsec_counter(int counter)
static void read_counter(int counter)
{
	u64 count[3], single_count[3];
	unsigned int cpu;
	int cpu;
	size_t res, nv;
	int scaled;
	int i, thread;
@@ -542,6 +543,8 @@ static const struct option options[] = {
		    "null run - dont start any counters"),
	OPT_BOOLEAN('B', "big-num", &big_num,
		    "print large numbers with thousands\' separators"),
	OPT_STRING('C', "cpu", &cpu_list, "cpu",
		    "list of cpus to monitor in system-wide"),
	OPT_END()
};

@@ -566,10 +569,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
	}

	if (system_wide)
		nr_cpus = read_cpu_map();
		nr_cpus = read_cpu_map(cpu_list);
	else
		nr_cpus = 1;

	if (nr_cpus < 1)
		usage_with_options(stat_usage, options);

	if (target_pid != -1) {
		target_tid = target_pid;
		thread_num = find_all_tid(target_pid, &all_tids);
Loading