Merge to Fedora kernel-2.6.7-1.492
[linux-2.6.git] / arch / i386 / kernel / smp.c
index 13c1714..c88dcbe 100644 (file)
@@ -159,7 +159,7 @@ void fastcall send_IPI_self(int vector)
  */
 inline void send_IPI_mask_bitmask(cpumask_t cpumask, int vector)
 {
-       unsigned long mask = cpus_coerce(cpumask);
+       unsigned long mask = cpus_addr(cpumask)[0];
        unsigned long cfg;
        unsigned long flags;
 
@@ -453,7 +453,7 @@ static void do_flush_tlb_all(void* info)
 
 void flush_tlb_all(void)
 {
-       on_each_cpu(do_flush_tlb_all, 0, 1, 1);
+       on_each_cpu(do_flush_tlb_all, NULL, 1, 1);
 }
 
 /*
@@ -494,7 +494,10 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
  * <func> The function to run. This must be fast and non-blocking.
  * <info> An arbitrary pointer to pass to the function.
  * <nonatomic> currently unused.
- * <wait> If true, wait (atomically) until function has completed on other CPUs.
+ * <wait> If 1, wait (atomically) until function has completed on other CPUs.
+ *        If 0, wait for the IPI to be received by other CPUs, but do not wait 
+ *        for the completion of the function on each CPU.  
+ *        If -1, do not wait for other CPUs to receive IPI.
  * [RETURNS] 0 on success, else a negative status code. Does not return until
  * remote CPUs are nearly ready to execute <<func>> or are or have executed.
  *
@@ -509,13 +512,14 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
                return 0;
 
        /* Can deadlock when called with interrupts disabled */
-       WARN_ON(irqs_disabled());
+       /* Only if we are waiting for other CPU to ack */
+       WARN_ON(irqs_disabled() && wait >= 0);
 
        data.func = func;
        data.info = info;
        atomic_set(&data.started, 0);
-       data.wait = wait;
-       if (wait)
+       data.wait = wait > 0 ? wait : 0;
+       if (wait > 0)
                atomic_set(&data.finished, 0);
 
        spin_lock(&call_lock);
@@ -526,10 +530,11 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
        send_IPI_allbutself(CALL_FUNCTION_VECTOR);
 
        /* Wait for response */
-       while (atomic_read(&data.started) != cpus)
-               barrier();
+       if (wait >= 0)
+               while (atomic_read(&data.started) != cpus)
+                       barrier();
 
-       if (wait)
+       if (wait > 0)
                while (atomic_read(&data.finished) != cpus)
                        barrier();
        spin_unlock(&call_lock);