Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4605

kernel-2.6.18-194.11.1.el5.src.rpm

From: Markus Armbruster <armbru@redhat.com>
Date: Thu, 7 Aug 2008 11:38:36 -0400
Subject: [xen] x86: xenoprof enable additional perf counters
Message-id: m3sktgu96r.fsf@crossbow.pond.sub.org
O-Subject: [PATCH RHEL-5.3] Xenoprof enable intel family 6 add'l perf counters
Bugzilla: 426096
RH-Acked-by: Rik van Riel <riel@redhat.com>
RH-Acked-by: Bill Burns <bburns@redhat.com>
RH-Acked-by: Chris Lalancette <clalance@redhat.com>
RH-Acked-by: Don Dutile <ddutile@redhat.com>

According to intel, our current hypervisor code can use only one
performance counter with intel family 6 cpus.  This patch fixes that.
Straight from upstream (xen-unstable.hg cset 16614).  I built rpms,
which intel tested successfully.

Bug 426096.  Please ACK.

# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1197628462 0
# Node ID 301507ac350a08335790b99ac845811cfc2b0a55
# Parent  61ff9b393c83d4750acdf2b26dd70fd7981e5145
xenoprof: Fix more than one events can't be sampled concurrently for Intel CPU with family equal to 6

The original code only sets EN bit of IA32_PERFEVTSEL0 when profiling
is started.

Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>

diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c
index 6c4344e..53ff218 100644
--- a/arch/x86/oprofile/op_model_ppro.c
+++ b/arch/x86/oprofile/op_model_ppro.c
@@ -104,6 +104,8 @@ static int ppro_check_ctrs(unsigned int const cpu,
 	int mode = xenoprofile_get_mode(current, regs);
 
 	for (i = 0 ; i < NUM_COUNTERS; ++i) {
+		if (!reset_value[i])
+			continue;
 		CTR_READ(low, high, msrs, i);
 		if (CTR_OVERFLOWED(low)) {
 			xenoprof_log_event(current, regs, eip, mode, i);
@@ -123,18 +125,30 @@ static int ppro_check_ctrs(unsigned int const cpu,
 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);
+	}
 }