* [patch] fix oprofile SMP ...
@ 2007-05-18 2:18 Davide Libenzi
2007-05-18 4:30 ` Andi Kleen
0 siblings, 1 reply; 2+ messages in thread
From: Davide Libenzi @ 2007-05-18 2:18 UTC (permalink / raw)
To: Linux Kernel Mailing List; +Cc: Benjamin LaHaise, Andi Kleen
This fixed oprofile being broken on x86-64 SMP. The current reservation
runs on all CPUs, but the ones following the first, will fail since the
reservation bitmap has an 1 in the MSR entry.
The reservation code should really run once, and their addresses used on
other CPUs. There are other solutions to this, but this is the simplest
and shorter one that came in my mind. Tested in my dual Opteron 252, and
working fine here.
Andi, if you don't like both Ben and my patch, would you mind fixing
oprofile yourself in some way?
Signed-off-by: Davide Libenzi <davidel@xmailserver.org>
- Davide
Index: linux-2.6.22-rc1-git6.oprof/arch/i386/oprofile/nmi_int.c
===================================================================
--- linux-2.6.22-rc1-git6.oprof.orig/arch/i386/oprofile/nmi_int.c 2007-05-17 18:32:48.000000000 -0700
+++ linux-2.6.22-rc1-git6.oprof/arch/i386/oprofile/nmi_int.c 2007-05-17 18:51:28.000000000 -0700
@@ -130,8 +130,19 @@
static void nmi_save_registers(void * dummy)
{
int cpu = smp_processor_id();
- struct op_msrs * msrs = &cpu_msrs[cpu];
- model->fill_in_addresses(msrs);
+ struct op_msrs *msrs = &cpu_msrs[cpu];
+
+ /*
+ * Use the CPU#0 already allocated addresses as reference.
+ */
+ if (cpu != 0) {
+ const struct op_msrs *rmsrs = &cpu_msrs[0];
+
+ memcpy(msrs->counters, rmsrs->counters,
+ model->num_counters * sizeof(msrs->counters[0]));
+ memcpy(msrs->controls, rmsrs->controls,
+ model->num_controls * sizeof(msrs->controls[0]));
+ }
nmi_cpu_save_registers(msrs);
}
@@ -195,6 +206,7 @@
static int nmi_setup(void)
{
int err=0;
+ struct op_msrs *msrs;
if (!allocate_msrs())
return -ENOMEM;
@@ -203,6 +215,14 @@
free_msrs();
return err;
}
+ /*
+ * MSR reservation should happen only once with the current API,
+ * otherwise CPU other then the first would fail to allocate.
+ * We do it here, and then we propagate the CPU#0 addresses to
+ * other CPUs.
+ */
+ msrs = &cpu_msrs[0];
+ model->fill_in_addresses(msrs);
/* We need to serialize save and setup for HT because the subset
* of msrs are distinct for save and setup operations
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [patch] fix oprofile SMP ...
2007-05-18 2:18 [patch] fix oprofile SMP Davide Libenzi
@ 2007-05-18 4:30 ` Andi Kleen
0 siblings, 0 replies; 2+ messages in thread
From: Andi Kleen @ 2007-05-18 4:30 UTC (permalink / raw)
To: Davide Libenzi; +Cc: Linux Kernel Mailing List, Benjamin LaHaise
On Friday 18 May 2007 04:18, Davide Libenzi wrote:
> This fixed oprofile being broken on x86-64 SMP. The current reservation
> runs on all CPUs, but the ones following the first, will fail since the
> reservation bitmap has an 1 in the MSR entry.
> The reservation code should really run once, and their addresses used on
> other CPUs. There are other solutions to this, but this is the simplest
> and shorter one that came in my mind. Tested in my dual Opteron 252, and
> working fine here.
> Andi, if you don't like both Ben and my patch, would you mind fixing
> oprofile yourself in some way?
Thanks, but I already did a very similar patch myself
-Andi
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.
Signed-off-by: Andi Kleen <ak@suse.de>
Index: linux/arch/i386/oprofile/nmi_int.c
===================================================================
--- linux.orig/arch/i386/oprofile/nmi_int.c
+++ linux/arch/i386/oprofile/nmi_int.c
@@ -131,7 +131,6 @@ static void nmi_save_registers(void * du
{
int cpu = smp_processor_id();
struct op_msrs * msrs = &cpu_msrs[cpu];
- model->fill_in_addresses(msrs);
nmi_cpu_save_registers(msrs);
}
@@ -195,6 +194,7 @@ static struct notifier_block profile_exc
static int nmi_setup(void)
{
int err=0;
+ int cpu;
if (!allocate_msrs())
return -ENOMEM;
@@ -207,6 +207,13 @@ 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)
+ cpu_msrs[cpu] = cpu_msrs[0];
+ }
on_each_cpu(nmi_save_registers, NULL, 0, 1);
on_each_cpu(nmi_cpu_setup, NULL, 0, 1);
nmi_enabled = 1;
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-05-18 4:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-18 2:18 [patch] fix oprofile SMP Davide Libenzi
2007-05-18 4:30 ` Andi Kleen
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.