Sophie

Sophie

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

kernel-2.6.18-194.11.1.el5.src.rpm

From: John Villalovos <jvillalo@redhat.com>
Date: Wed, 16 Sep 2009 13:54:48 -0400
Subject: [x86] oprofile: fix K8/core2 on multiple cpus
Message-id: 20090916175447.GB5238@linuxjohn.usersys.redhat.com
O-Subject: [RHEL 5.5 BZ523479 Patch 2/3] Support arch perfmon in oprofile
Bugzilla: 523479
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>

[RHEL 5.5 BZ523479 Patch 2/3] Support arch perfmon in oprofile
https://bugzilla.redhat.com/show_bug.cgi?id=523479

This second patch is some fixes that were needed for the performance counter
reservation system, before applying the third set of patches.

commit 3f85f9b0c07ea02cdaf19c46539175f360ffe97c
Author: John L. Villalovos <jvillalo@redhat.com>
Date:   Tue Sep 15 13:35:33 2009 -0400

    Backport of the following commits:
        Upstream commit 6c977aad03a18019015035958c65b6729cd0574c
        Upstream Author: Andi Kleen <ak@suse.de>
        Upstream Date:   Mon May 21 14:31:45 2007 +0200

    	i386: Fix K8/core2 oprofile on multiple CPUs

    	Only try to allocate MSRs once instead of for every CPU.

    	This assumes the MSRs are the same on all CPUs which is currently
    	true. P4-HT is a special case for different SMT threads, but the code
    	always saves/restores all MSRs so it works identical.

        Upstream commit 0939c17c7bcf1c838bea4445b80a6966809a438f
        Upstream Author: Chris Wright <chrisw@sous-sol.org>
        Upstream Date:   Fri Jun 1 00:46:39 2007 -0700

    	x86: fix oprofile double free

    	Chuck reports that the recent fix from Andi to oprofile
    	6c977aad03a18019015035958c65b6729cd0574c introduces a double free.  Each
    	cpu's cpu_msrs is setup to point to cpu 0's, which causes free_msrs to free
    	cpu 0's pointers for_each_possible_cpu.  Rather than copy the pointers, do
    	a deep copy instead.

        Upstream commit 0f8e45a288991ff24951b83fe83cf3eb011bbaed
        Upstream Author: Stephane Eranian <eranian@hpl.hp.com>
        Upstream Date:   Wed Oct 17 18:04:32 2007 +0200

    	i386: make Oprofile call shutdown() only once per session

    	Oprofile: call model->shutdown() only once to avoid calling release_ev*()
    	multiple times

diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
index 6889f03..fc98c05 100644
--- a/arch/i386/oprofile/nmi_int.c
+++ b/arch/i386/oprofile/nmi_int.c
@@ -121,7 +121,6 @@ static void nmi_save_registers(void * dummy)
 {
 	int cpu = smp_processor_id();
 	struct op_msrs * msrs = &cpu_msrs[cpu];
-	model->fill_in_addresses(msrs);
 	nmi_cpu_save_registers(msrs);
 }
 
@@ -145,7 +144,7 @@ static int allocate_msrs(void)
 	size_t counters_size = sizeof(struct op_msr) * model->num_counters;
 
 	int i;
-	for_each_online_cpu(i) {
+	for_each_possible_cpu(i) {
 		cpu_msrs[i].counters = kmalloc(counters_size, GFP_KERNEL);
 		if (!cpu_msrs[i].counters) {
 			success = 0;
@@ -179,6 +178,8 @@ static void nmi_cpu_setup(void * dummy)
 
 static int nmi_setup(void)
 {
+	int cpu;
+
 	if (!allocate_msrs())
 		return -ENOMEM;
 
@@ -199,6 +200,19 @@ static int nmi_setup(void)
 	/* We need to serialize save and setup for HT because the subset
 	 * of msrs are distinct for save and setup operations
 	 */
+
+	/* Assume saved/restored counters are the same on all CPUs */
+	model->fill_in_addresses(&cpu_msrs[0]);
+	for_each_possible_cpu(cpu) {
+		if (cpu != 0) {
+			memcpy(cpu_msrs[cpu].counters, cpu_msrs[0].counters,
+				sizeof(struct op_msr) * model->num_counters);
+
+			memcpy(cpu_msrs[cpu].controls, cpu_msrs[0].controls,
+				sizeof(struct op_msr) * model->num_controls);
+		}
+
+	}
 	on_each_cpu(nmi_save_registers, NULL, 0, 1);
 	on_each_cpu(nmi_cpu_setup, NULL, 0, 1);
 	set_nmi_callback(nmi_callback);
@@ -249,7 +263,6 @@ static void nmi_cpu_shutdown(void * dummy)
 	apic_write(APIC_LVTPC, saved_lvtpc[cpu]);
 	apic_write(APIC_LVTERR, v);
 	nmi_restore_registers(msrs);
-	model->shutdown(msrs);
 }
 
  
@@ -258,6 +271,7 @@ static void nmi_shutdown(void)
 	nmi_enabled = 0;
 	on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
 	unset_nmi_callback();
+	model->shutdown(cpu_msrs);
 	release_lapic_nmi();
 	free_msrs();