[COMMIT master] smp: fix race in async on_cpu()

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

 



From: Avi Kivity <avi@xxxxxxxxxx>

We fire off the IPI, but don't wait for the other cpu to pickk up
the function and data before returning.

Fix by making the other cpu ACK the receipt of the IPI (but still
execute the result asynchrously).

Signed-off-by: Avi Kivity <avi@xxxxxxxxxx>

diff --git a/lib/x86/smp.c b/lib/x86/smp.c
index 241f755..8da614a 100644
--- a/lib/x86/smp.c
+++ b/lib/x86/smp.c
@@ -7,15 +7,27 @@
 #define IPI_VECTOR 0x20
 
 static struct spinlock ipi_lock;
-static void (*ipi_function)(void *data);
-static void *ipi_data;
+static volatile void (*ipi_function)(void *data);
+static volatile void *ipi_data;
 static volatile int ipi_done;
+static volatile bool ipi_wait;
+static int _cpu_count;
 
 static __attribute__((used)) void ipi()
 {
-    ipi_function(ipi_data);
-    apic_write(APIC_EOI, 0);
-    ipi_done = 1;
+    void (*function)(void *data) = ipi_function;
+    void *data = ipi_data;
+    bool wait = ipi_wait;
+
+    if (!wait) {
+	ipi_done = 1;
+	apic_write(APIC_EOI, 0);
+    }
+    function(data);
+    if (wait) {
+	ipi_done = 1;
+	apic_write(APIC_EOI, 0);
+    }
 }
 
 asm (
@@ -92,13 +104,12 @@ static void __on_cpu(int cpu, void (*function)(void *data), void *data,
 	ipi_done = 0;
 	ipi_function = function;
 	ipi_data = data;
+	ipi_wait = wait;
 	apic_icr_write(APIC_INT_ASSERT | APIC_DEST_PHYSICAL | APIC_DM_FIXED
                        | IPI_VECTOR,
                        cpu);
-	if (wait) {
-		while (!ipi_done)
-		    ;
-	}
+	while (!ipi_done)
+	    ;
     }
     spin_unlock(&ipi_lock);
 }
--
To unsubscribe from this list: send the line "unsubscribe kvm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM Development]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Walks]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux