ppc64 HW profiling support for oprofile

Anton Blanchard anton at samba.org
Tue Apr 13 23:02:17 EST 2004


Hi,

Support for using HW performance counters in ppc64 oprofile has just
been merged into 2.6. Attached is the userspace patch, it should apply
against latest CVS.

Also attached is a dodgy script used to program the PMCs. POWER4 and 970
have a complex design which is best programmed from userspace. The PMCs
are exported via sysfs so userspace programs can do the setup. Oprofile
then just counts opaque events (events are called PMC1 - PMC8).

pmc_it is that dodgy script and takes an input file in the form:

mmcr0:mmcr1:mmcra

and applies it to all cpus via sysfs. I expect we will have a better
solution soon (maybe opcontrol should call out to something that
calculates mmcr0,1,a and programs them).

pmc_cycles is a very simple setup, counting cycles on PMC1. More
combinations should be on the way soon.

An example run:

power4/970:

# pmc_it pmc_cycles
# opcontrol --setup --vmlinux=/root/vmlinux -e PMC1:100000:0:1:1
# opcontrol --start
[ do stuff ]
# opreport -nl

power3/rs64:

# opcontrol --setup --vmlinux=/root/vmlinux -e CYCLES:100000:0:1:1
# opcontrol --start
[ do stuff ]
# opreport -nl
-------------- next part --------------
diff --exclude=CVS -urN oprofile.orig/events/Makefile.am oprofile/events/Makefile.am
--- oprofile.orig/events/Makefile.am	2004-04-13 22:06:22.739166304 +1000
+++ oprofile/events/Makefile.am	2004-04-13 21:32:11.025170320 +1000
@@ -14,6 +14,11 @@
 	ia64/ia64/events ia64/ia64/unit_masks \
 	ia64/itanium2/events ia64/itanium2/unit_masks \
 	ia64/itanium/events ia64/itanium/unit_masks \
+	ppc64/970/events ppc64/970/unit_masks \
+	ppc64/rs64/events ppc64/rs64/unit_masks \
+	ppc64/power3/events ppc64/power3/unit_masks \
+	ppc64/power4/events ppc64/power4/unit_masks \
+	ppc64/power5/events ppc64/power5/unit_masks \
 	rtc/events rtc/unit_masks \
 	x86-64/hammer/events x86-64/hammer/unit_masks \
 	arm/xscale1/events arm/xscale1/unit_masks \
diff --exclude=CVS -urN oprofile.orig/events/ppc64/970/events oprofile/events/ppc64/970/events
--- oprofile.orig/events/ppc64/970/events	1970-01-01 10:00:00.000000000 +1000
+++ oprofile/events/ppc64/970/events	2004-04-13 21:45:30.066238960 +1000
@@ -0,0 +1,10 @@
+# ppc64 970 events
+#
+event:0x00 counters:0 um:zero minimum:1000 name:PMC1 : PMC1
+event:0x01 counters:1 um:zero minimum:1000 name:PMC2 : PMC2
+event:0x02 counters:2 um:zero minimum:1000 name:PMC3 : PMC3
+event:0x03 counters:3 um:zero minimum:1000 name:PMC4 : PMC4
+event:0x04 counters:4 um:zero minimum:1000 name:PMC5 : PMC5
+event:0x05 counters:5 um:zero minimum:1000 name:PMC6 : PMC6
+event:0x06 counters:6 um:zero minimum:1000 name:PMC7 : PMC7
+event:0x07 counters:7 um:zero minimum:1000 name:PMC8 : PMC8
diff --exclude=CVS -urN oprofile.orig/events/ppc64/970/unit_masks oprofile/events/ppc64/970/unit_masks
--- oprofile.orig/events/ppc64/970/unit_masks	1970-01-01 10:00:00.000000000 +1000
+++ oprofile/events/ppc64/970/unit_masks	2004-04-11 16:06:55.000000000 +1000
@@ -0,0 +1,4 @@
+# ppc64 970 possible unit masks
+#
+name:zero type:mandatory default:0x0
+	0x0 No unit mask
diff --exclude=CVS -urN oprofile.orig/events/ppc64/power3/events oprofile/events/ppc64/power3/events
--- oprofile.orig/events/ppc64/power3/events	1970-01-01 10:00:00.000000000 +1000
+++ oprofile/events/ppc64/power3/events	2004-04-13 22:04:54.374155664 +1000
@@ -0,0 +1,8 @@
+# ppc64 POWER3 events
+#
+event:0x00 counters:0 um:zero minimum:1000 name:CYCLES : Total cycles
+#
+event:0x5 counters:0 um:zero minimum:1000 name:L1_ICACHE_MISS : Level 1 icache misses
+event:0x6 counters:0 um:zero minimum:1000 name:L1_DCACHE_MISS : Level 1 dcache misses
+#
+event:0x13 counters:0 um:zero minimum:1000 name:TLB_MISS : TLB misses
diff --exclude=CVS -urN oprofile.orig/events/ppc64/power3/unit_masks oprofile/events/ppc64/power3/unit_masks
--- oprofile.orig/events/ppc64/power3/unit_masks	1970-01-01 10:00:00.000000000 +1000
+++ oprofile/events/ppc64/power3/unit_masks	2004-04-11 16:06:55.000000000 +1000
@@ -0,0 +1,4 @@
+# ppc64 POWER3 possible unit masks
+#
+name:zero type:mandatory default:0x0
+	0x0 No unit mask
diff --exclude=CVS -urN oprofile.orig/events/ppc64/power4/events oprofile/events/ppc64/power4/events
--- oprofile.orig/events/ppc64/power4/events	1970-01-01 10:00:00.000000000 +1000
+++ oprofile/events/ppc64/power4/events	2004-04-13 21:46:10.163133624 +1000
@@ -0,0 +1,10 @@
+# ppc64 POWER4 events
+#
+event:0x00 counters:0 um:zero minimum:1000 name:PMC1 : PMC1
+event:0x01 counters:1 um:zero minimum:1000 name:PMC2 : PMC2
+event:0x02 counters:2 um:zero minimum:1000 name:PMC3 : PMC3
+event:0x03 counters:3 um:zero minimum:1000 name:PMC4 : PMC4
+event:0x04 counters:4 um:zero minimum:1000 name:PMC5 : PMC5
+event:0x05 counters:5 um:zero minimum:1000 name:PMC6 : PMC6
+event:0x06 counters:6 um:zero minimum:1000 name:PMC7 : PMC7
+event:0x07 counters:7 um:zero minimum:1000 name:PMC8 : PMC8
diff --exclude=CVS -urN oprofile.orig/events/ppc64/power4/unit_masks oprofile/events/ppc64/power4/unit_masks
--- oprofile.orig/events/ppc64/power4/unit_masks	1970-01-01 10:00:00.000000000 +1000
+++ oprofile/events/ppc64/power4/unit_masks	2004-04-11 16:06:55.000000000 +1000
@@ -0,0 +1,4 @@
+# ppc64 POWER4 possible unit masks
+#
+name:zero type:mandatory default:0x0
+	0x0 No unit mask
diff --exclude=CVS -urN oprofile.orig/events/ppc64/power5/events oprofile/events/ppc64/power5/events
--- oprofile.orig/events/ppc64/power5/events	1970-01-01 10:00:00.000000000 +1000
+++ oprofile/events/ppc64/power5/events	2004-04-13 21:45:54.589237048 +1000
@@ -0,0 +1,8 @@
+# ppc64 POWER5 events
+#
+event:0x00 counters:0 um:zero minimum:1000 name:PMC1 : PMC1
+event:0x01 counters:1 um:zero minimum:1000 name:PMC2 : PMC2
+event:0x02 counters:2 um:zero minimum:1000 name:PMC3 : PMC3
+event:0x03 counters:3 um:zero minimum:1000 name:PMC4 : PMC4
+event:0x04 counters:4 um:zero minimum:1000 name:PMC5 : PMC5
+event:0x05 counters:5 um:zero minimum:1000 name:PMC6 : PMC6
diff --exclude=CVS -urN oprofile.orig/events/ppc64/power5/unit_masks oprofile/events/ppc64/power5/unit_masks
--- oprofile.orig/events/ppc64/power5/unit_masks	1970-01-01 10:00:00.000000000 +1000
+++ oprofile/events/ppc64/power5/unit_masks	2004-04-11 16:06:55.000000000 +1000
@@ -0,0 +1,4 @@
+# ppc64 POWER5 possible unit masks
+#
+name:zero type:mandatory default:0x0
+	0x0 No unit mask
diff --exclude=CVS -urN oprofile.orig/events/ppc64/rs64/events oprofile/events/ppc64/rs64/events
--- oprofile.orig/events/ppc64/rs64/events	1970-01-01 10:00:00.000000000 +1000
+++ oprofile/events/ppc64/rs64/events	2004-04-13 22:00:18.108223000 +1000
@@ -0,0 +1,12 @@
+# ppc64 RS64 events
+#
+event:0x01 counters:0,1,2,3,4,5,6,7 um:zero minimum:1000 name:CYCLES : Total cycles
+#
+event:0x0a counters:1,3,5,7 um:zero minimum:1000 name:L1_ICACHE_MISS : Level 1 icache misses
+event:0x0c counters:0,2,4,6 um:zero minimum:1000 name:L1_DCACHE_MISS : Level 1 dcache misses
+#
+event:0x55 counters:0 um:zero minimum:1000 name:TLB_I_MISS : Instruction TLB misses
+event:0x55 counters:2 um:zero minimum:1000 name:TLB_D_MISS : Data TLB misses
+#
+event:0x5d counters:0 um:zero minimum:1000 name:SLB_I_MISS : Instruction SLB misses
+event:0x5d counters:2 um:zero minimum:1000 name:SLB_D_MISS : Data SLB misses
diff --exclude=CVS -urN oprofile.orig/events/ppc64/rs64/unit_masks oprofile/events/ppc64/rs64/unit_masks
--- oprofile.orig/events/ppc64/rs64/unit_masks	1970-01-01 10:00:00.000000000 +1000
+++ oprofile/events/ppc64/rs64/unit_masks	2004-04-11 16:06:55.000000000 +1000
@@ -0,0 +1,4 @@
+# ppc64 RS64 possible unit masks
+#
+name:zero type:mandatory default:0x0
+	0x0 No unit mask
diff --exclude=CVS -urN oprofile.orig/libop/op_cpu_type.c oprofile/libop/op_cpu_type.c
--- oprofile.orig/libop/op_cpu_type.c	2004-04-13 22:06:23.547176640 +1000
+++ oprofile/libop/op_cpu_type.c	2004-04-13 21:34:01.932216160 +1000
@@ -43,6 +43,11 @@
 	{ "Pentium M (P6 core)", "i386/p6_mobile", CPU_P6_MOBILE, 2 },
 	{ "ARM/XScale PMU1", "arm/xscale1", CPU_ARM_XSCALE1, 3 },
 	{ "ARM/XScale PMU2", "arm/xscale2", CPU_ARM_XSCALE2, 5 },
+	{ "ppc64 RS64", "ppc64/rs64", CPU_PPC64_RS64, 8 },
+	{ "ppc64 POWER3", "ppc64/power3", CPU_PPC64_POWER3, 8 },
+	{ "ppc64 POWER4", "ppc64/power4", CPU_PPC64_POWER4, 8 },
+	{ "ppc64 970", "ppc64/970", CPU_PPC64_970, 8 },
+	{ "ppc64 POWER5", "ppc64/power5", CPU_PPC64_POWER5, 6 },
 };

 static size_t const nr_cpu_descrs = sizeof(cpu_descrs) / sizeof(struct cpu_descr);
diff --exclude=CVS -urN oprofile.orig/libop/op_cpu_type.h oprofile/libop/op_cpu_type.h
--- oprofile.orig/libop/op_cpu_type.h	2004-04-13 22:06:23.572172840 +1000
+++ oprofile/libop/op_cpu_type.h	2004-04-13 21:34:25.528222608 +1000
@@ -39,6 +39,11 @@
 	CPU_P6_MOBILE, /**< Pentium M series */
 	CPU_ARM_XSCALE1, /**< ARM XScale 1 */
 	CPU_ARM_XSCALE2, /**< ARM XScale 2 */
+	CPU_PPC64_RS64, /**< ppc64 RS64 family */
+	CPU_PPC64_POWER3, /**< ppc64 RS64 family */
+	CPU_PPC64_POWER4, /**< ppc64 POWER4 family */
+	CPU_PPC64_970, /**< ppc64 970 family */
+	CPU_PPC64_POWER5, /**< ppc64 POWER5 family */
 	MAX_CPU_TYPE
 } op_cpu;

diff --exclude=CVS -urN oprofile.orig/libop/op_events.c oprofile/libop/op_events.c
--- oprofile.orig/libop/op_events.c	2004-04-13 22:06:23.897123440 +1000
+++ oprofile/libop/op_events.c	2004-04-13 21:34:51.690239936 +1000
@@ -651,6 +651,14 @@
 			descr->name = "CPU_CYCLES";
 			break;

+		case CPU_PPC64_RS64:
+		case CPU_PPC64_POWER3:
+		case CPU_PPC64_POWER4:
+		case CPU_PPC64_970:
+		case CPU_PPC64_POWER5:
+			descr->name = "CYCLES";
+			break;
+
 		// don't use default, if someone add a cpu he wants a compiler
 		// warning if he forgets to handle it here.
 		case CPU_TIMER_INT:
diff --exclude=CVS -urN oprofile.orig/utils/op_help.c oprofile/utils/op_help.c
--- oprofile.orig/utils/op_help.c	2004-04-13 22:06:24.407180072 +1000
+++ oprofile/utils/op_help.c	2004-04-13 21:44:10.369240328 +1000
@@ -403,6 +403,14 @@
 		printf("See Intel XScale Core Developer's Manual\n"
 		       "Chapter 8 Performance Monitoring\n");
 		break;
+	case CPU_PPC64_RS64:
+	case CPU_PPC64_POWER3:
+	case CPU_PPC64_POWER4:
+	case CPU_PPC64_970:
+	case CPU_PPC64_POWER5:
+		printf("See PowerPC Architecture Book 3\n"
+		       "http://www-106.ibm.com/developerworks/eserver/articles/archguide.html\n");
+		break;
 	case CPU_RTC:
 		break;

-------------- next part --------------
#!/usr/bin/perl -w

use strict;

my @cpus;

open(CPUINFO, "/proc/cpuinfo") || die("could not open /proc/cpuinfo");
while(<CPUINFO>) {
	if (/processor/) {
		my ($junk, $cpu) = split(/:/);
		push @cpus, $cpu;
	}
}
close(CPUINFO);

while(<>) {
	if (/^#/) {
		print $_;
		next;
	}

	chop;

	my ($mmcr0, $mmcr1, $mmcra) = split(/:/);

	my $cpu;
	for $cpu (@cpus) {
		my $cpufile = sprintf("/sys/devices/system/cpu/cpu%d", $cpu);
		system("echo $mmcr0 > $cpufile/mmcr0");
		system("echo $mmcr1 > $cpufile/mmcr1");
		system("echo $mmcra > $cpufile/mmcra");
	}
}
-------------- next part --------------
# format: mmcr0:mmcr1:mmcra
#
# cycles in PMC1
00000700:0:0


More information about the Linuxppc64-dev mailing list