[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86 mtrr: Fix set_mtrr() race against cpu_online_map changes.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1275385206 -3600
# Node ID 2f765c9825b22c4f6d335d6ab126a69b94222f02
# Parent  458589ad3793ca68be1a067683e6b22d918a4ceb
x86 mtrr: Fix set_mtrr() race against cpu_online_map changes.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/cpu/mtrr/main.c |   25 ++++++++++++++-----------
 1 files changed, 14 insertions(+), 11 deletions(-)

diff -r 458589ad3793 -r 2f765c9825b2 xen/arch/x86/cpu/mtrr/main.c
--- a/xen/arch/x86/cpu/mtrr/main.c      Tue Jun 01 07:06:50 2010 +0100
+++ b/xen/arch/x86/cpu/mtrr/main.c      Tue Jun 01 10:40:06 2010 +0100
@@ -229,29 +229,32 @@ static void set_mtrr(unsigned int reg, u
 static void set_mtrr(unsigned int reg, unsigned long base,
                     unsigned long size, mtrr_type type)
 {
+       cpumask_t allbutself;
+       unsigned int nr_cpus;
        struct set_mtrr_data data;
        unsigned long flags;
+
+       allbutself = cpu_online_map;
+       cpu_clear(smp_processor_id(), allbutself);
+       nr_cpus = cpus_weight(allbutself);
 
        data.smp_reg = reg;
        data.smp_base = base;
        data.smp_size = size;
        data.smp_type = type;
-       atomic_set(&data.count, num_online_cpus() - 1);
-       /* make sure data.count is visible before unleashing other CPUs */
-       smp_wmb();
+       atomic_set(&data.count, nr_cpus);
        atomic_set(&data.gate,0);
 
-       /*  Start the ball rolling on other CPUs  */
-       if (smp_call_function(ipi_handler, &data, 0) != 0)
-               panic("mtrr: timed out waiting for other CPUs\n");
+       /* Start the ball rolling on other CPUs */
+       on_selected_cpus(&allbutself, ipi_handler, &data, 0);
 
        local_irq_save(flags);
 
-       while(atomic_read(&data.count))
+       while (atomic_read(&data.count))
                cpu_relax();
 
        /* ok, reset count and toggle gate */
-       atomic_set(&data.count, num_online_cpus() - 1);
+       atomic_set(&data.count, nr_cpus);
        smp_wmb();
        atomic_set(&data.gate,1);
 
@@ -271,10 +274,10 @@ static void set_mtrr(unsigned int reg, u
                mtrr_if->set(reg,base,size,type);
 
        /* wait for the others */
-       while(atomic_read(&data.count))
+       while (atomic_read(&data.count))
                cpu_relax();
 
-       atomic_set(&data.count, num_online_cpus() - 1);
+       atomic_set(&data.count, nr_cpus);
        smp_wmb();
        atomic_set(&data.gate,0);
 
@@ -282,7 +285,7 @@ static void set_mtrr(unsigned int reg, u
         * Wait here for everyone to have seen the gate change
         * So we're the last ones to touch 'data'
         */
-       while(atomic_read(&data.count))
+       while (atomic_read(&data.count))
                cpu_relax();
 
        local_irq_restore(flags);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.