-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf tools: Fix sparse CPU numbering related bugs
At present, the perf subcommands that do system-wide monitoring (perf stat, perf record and perf top) don't work properly unless the online cpus are numbered 0, 1, ..., N-1. These tools ask for the number of online cpus with sysconf(_SC_NPROCESSORS_ONLN) and then try to create events for cpus 0, 1, ..., N-1. This creates problems for systems where the online cpus are numbered sparsely. For example, a POWER6 system in single-threaded mode (i.e. only running 1 hardware thread per core) will have only even-numbered cpus online. This fixes the problem by reading the /sys/devices/system/cpu/online file to find out which cpus are online. The code that does that is in tools/perf/util/cpumap.[ch], and consists of a read_cpu_map() function that sets up a cpumap[] array and returns the number of online cpus. If /sys/devices/system/cpu/online can't be read or can't be parsed successfully, it falls back to using sysconf to ask how many cpus are online and sets up an identity map in cpumap[]. The perf record, perf stat and perf top code then calls read_cpu_map() in the system-wide monitoring case (instead of sysconf) and uses cpumap[] to get the cpu numbers to pass to perf_event_open. Signed-off-by: Paul Mackerras <paulus@samba.org> Cc: Anton Blanchard <anton@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@infradead.org> LKML-Reference: <20100310093609.GA3959@brick.ozlabs.ibm.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
- Loading branch information
Paul Mackerras
authored and
Ingo Molnar
committed
Mar 11, 2010
1 parent
220b140
commit a12b51c
Showing
6 changed files
with
81 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#include "util.h" | ||
#include "../perf.h" | ||
#include "cpumap.h" | ||
#include <assert.h> | ||
#include <stdio.h> | ||
|
||
int cpumap[MAX_NR_CPUS]; | ||
|
||
static int default_cpu_map(void) | ||
{ | ||
int nr_cpus, i; | ||
|
||
nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); | ||
assert(nr_cpus <= MAX_NR_CPUS); | ||
assert((int)nr_cpus >= 0); | ||
|
||
for (i = 0; i < nr_cpus; ++i) | ||
cpumap[i] = i; | ||
|
||
return nr_cpus; | ||
} | ||
|
||
int read_cpu_map(void) | ||
{ | ||
FILE *onlnf; | ||
int nr_cpus = 0; | ||
int n, cpu, prev; | ||
char sep; | ||
|
||
onlnf = fopen("/sys/devices/system/cpu/online", "r"); | ||
if (!onlnf) | ||
return default_cpu_map(); | ||
|
||
sep = 0; | ||
prev = -1; | ||
for (;;) { | ||
n = fscanf(onlnf, "%u%c", &cpu, &sep); | ||
if (n <= 0) | ||
break; | ||
if (prev >= 0) { | ||
assert(nr_cpus + cpu - prev - 1 < MAX_NR_CPUS); | ||
while (++prev < cpu) | ||
cpumap[nr_cpus++] = prev; | ||
} | ||
assert (nr_cpus < MAX_NR_CPUS); | ||
cpumap[nr_cpus++] = cpu; | ||
if (n == 2 && sep == '-') | ||
prev = cpu; | ||
else | ||
prev = -1; | ||
if (n == 1 || sep == '\n') | ||
break; | ||
} | ||
fclose(onlnf); | ||
if (nr_cpus > 0) | ||
return nr_cpus; | ||
|
||
return default_cpu_map(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#ifndef __PERF_CPUMAP_H | ||
#define __PERF_CPUMAP_H | ||
|
||
extern int read_cpu_map(void); | ||
extern int cpumap[]; | ||
|
||
#endif /* __PERF_CPUMAP_H */ |