Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 2486

kernel-2.6.18-128.1.10.el5.src.rpm

From: Markus Armbruster <armbru@redhat.com>
Date: Wed, 13 Aug 2008 16:59:38 -0400
Subject: [x86] oprofile: enable additional perf counters
Message-id: m3iqu4fx6t.fsf@crossbow.pond.sub.org
O-Subject: [PATCH RHEL-5.3] Oprofile enable intel family 6 add'l perf counters
Bugzilla: 426096
RH-Acked-by: Anton Arapov <aarapov@redhat.com>
RH-Acked-by: Rik van Riel <riel@redhat.com>
RH-Acked-by: Bill Burns <bburns@redhat.com>

Our current oprofile code can use only one performance counter with
intel family 6 cpus.  This was fixed upstream:

commit 6b77df08a36d989f7dd00ccb6a026a0e96170d16
Author: Arun Sharma <arun.sharma@google.com>
Date:   Fri Sep 29 02:00:01 2006 -0700

    [PATCH] oprofile: ppro: need to enable/disable all the counters

    Need to enable/disable all the counters instead of just counter 0.

    This affects all cpus with family=6, including i386/core.  Usual symptom:
    only counter 0 provides samples.  Other counters don't produce samples.

Unfortunately, that patch doesn't apply, because it depends on this
one:

commit cb9c448c661d40ce2efbce8e9c19cc4d420d8ccc
Author: Don Zickus <dzickus@redhat.com>
Date:   Tue Sep 26 10:52:26 2006 +0200

    [PATCH] i386: Utilize performance counter reservation framework in oprofile

    Incorporates the new performance counter reservation system in oprofile.
    Also cleans up a lot of the initialization code.  The code original zero'd
    out every register associated with performance counters regardless if those
    registers were used or not.  This causes issues with the nmi watchdog.
    Now oprofile tries to reserve registers and gives up if it can't get them.

which is just one part of a fairly invasive rework of the NMI
watchdog.  I figure we just need parts of the initialization cleanup
here, but please review that idea critically.

The patch is very close to the one we already took to fix the same
issue for the hypervisor (bug 426096).

I built rpms, which intel tested successfully.

Bug 458824.  Please ACK.

diff --git a/arch/i386/oprofile/op_model_ppro.c b/arch/i386/oprofile/op_model_ppro.c
index 5e2b21f..daf581e 100644
--- a/arch/i386/oprofile/op_model_ppro.c
+++ b/arch/i386/oprofile/op_model_ppro.c
@@ -93,6 +93,8 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
 	int i;
  
 	for (i = 0 ; i < NUM_COUNTERS; ++i) {
+		if (!reset_value[i])
+			continue;
 		CTR_READ(low, high, msrs, i);
 		if (CTR_OVERFLOWED(low)) {
 			oprofile_add_sample(regs, i);
@@ -118,18 +120,30 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
 static void ppro_start(struct op_msrs const * const msrs)
 {
 	unsigned int low,high;
-	CTRL_READ(low, high, msrs, 0);
-	CTRL_SET_ACTIVE(low);
-	CTRL_WRITE(low, high, msrs, 0);
+	int i;
+
+	for (i = 0; i < NUM_COUNTERS; ++i) {
+		if (reset_value[i]) {
+			CTRL_READ(low, high, msrs, i);
+			CTRL_SET_ACTIVE(low);
+			CTRL_WRITE(low, high, msrs, i);
+		}
+	}
 }
 
 
 static void ppro_stop(struct op_msrs const * const msrs)
 {
 	unsigned int low,high;
-	CTRL_READ(low, high, msrs, 0);
-	CTRL_SET_INACTIVE(low);
-	CTRL_WRITE(low, high, msrs, 0);
+	int i;
+
+	for (i = 0; i < NUM_COUNTERS; ++i) {
+		if (!reset_value[i])
+			continue;
+		CTRL_READ(low, high, msrs, i);
+		CTRL_SET_INACTIVE(low);
+		CTRL_WRITE(low, high, msrs, i);
+	}
 }