[2.5][14/14] smp_call_function_on_cpu - x86_64

[2.5][14/14] smp_call_function_on_cpu - x86_64

Post by Zwane Mwaikamb » Sat, 15 Feb 2003 12:10:08



 smp.c |   48 ++++++++++++++++++++++++++++++++----------------
 1 files changed, 32 insertions(+), 16 deletions(-)

Index: linux-2.5.60/arch/x86_64/kernel/smp.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.60/arch/x86_64/kernel/smp.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 smp.c
--- linux-2.5.60/arch/x86_64/kernel/smp.c       10 Feb 2003 22:15:09 -0000      1.1.1.1

  * in the system.
  */

-int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
-                       int wait)
 /*
- * [SUMMARY] Run a function on all other CPUs.
- * <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.
- * [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.
+ * smp_call_function_on_cpu - Runs func on all processors in the mask
+ *




+ *
+ * Returns 0 on success, else a negative status code. Does not return until
+ * remote CPUs are nearly ready to execute func or have executed it.
  *
  * You must not call this function with disabled interrupts or from a
  * hardware interrupt handler or from a bottom half handler.
  */
+
+int smp_call_function_on_cpu (void (*func) (void *info), void *info, int wait,
+                               unsigned long mask)
 {
        struct call_data_struct data;
-       int cpus = num_online_cpus()-1;
+       int i, cpu, num_cpus;
+

-       if (!cpus)
-               return 0;
+       cpu = get_cpu();
+       mask &= ~(1UL << cpu);
+       num_cpus = hweight64(mask);
+       if (num_cpus == 0) {
+               put_cpu_no_resched();
+               return -EINVAL;
+       }

        data.func = func;

        spin_lock(&call_lock);
        call_data = &data;
        wmb();
+
        /* Send a message to all other CPUs and wait for them to respond */
-       send_IPI_allbutself(CALL_FUNCTION_VECTOR);
+       send_IPI_mask(mask, CALL_FUNCTION_VECTOR);

        /* Wait for response */
-       while (atomic_read(&data.started) != cpus)
+       while (atomic_read(&data.started) != num_cpus)
                barrier();

        if (wait)
-               while (atomic_read(&data.finished) != cpus)
+               while (atomic_read(&data.finished) != num_cpus)
                        barrier();
        spin_unlock(&call_lock);
-
+       put_cpu_no_resched();
        return 0;
+}
+
+int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
+                       int wait)
+{
+       return smp_call_function_on_cpu(func, info, wait, cpu_online_map);
 }

 static void stop_this_cpu (void * dummy)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

[2.5][14/14] smp_call_function_on_cpu - x86_64

Post by Zwane Mwaikamb » Sat, 15 Feb 2003 15:00:15


One liner to fix num_cpus == 0 on SMP kernel w/ UP box

Index: linux-2.5.60/arch/x86_64/kernel/smp.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.60/arch/x86_64/kernel/smp.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 smp.c
--- linux-2.5.60/arch/x86_64/kernel/smp.c       10 Feb 2003 22:15:09 -0000      1.1.1.1

  * in the system.
  */

-int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
-                       int wait)
 /*
- * [SUMMARY] Run a function on all other CPUs.
- * <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.
- * [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.
+ * smp_call_function_on_cpu - Runs func on all processors in the mask
+ *




+ *
+ * Returns 0 on success, else a negative status code. Does not return until
+ * remote CPUs are nearly ready to execute func or have executed it.
  *
  * You must not call this function with disabled interrupts or from a
  * hardware interrupt handler or from a bottom half handler.
  */
+
+int smp_call_function_on_cpu (void (*func) (void *info), void *info, int wait,
+                               unsigned long mask)
 {
        struct call_data_struct data;
-       int cpus = num_online_cpus()-1;
+       int i, cpu, num_cpus;
+

-       if (!cpus)
+       cpu = get_cpu();
+       mask &= ~(1UL << cpu);
+       num_cpus = hweight64(mask);
+       if (num_cpus == 0) {
+               put_cpu_no_resched();
                return 0;
+       }

        data.func = func;

        spin_lock(&call_lock);
        call_data = &data;
        wmb();
+
        /* Send a message to all other CPUs and wait for them to respond */
-       send_IPI_allbutself(CALL_FUNCTION_VECTOR);
+       send_IPI_mask(mask, CALL_FUNCTION_VECTOR);

        /* Wait for response */
-       while (atomic_read(&data.started) != cpus)
+       while (atomic_read(&data.started) != num_cpus)
                barrier();

        if (wait)
-               while (atomic_read(&data.finished) != cpus)
+               while (atomic_read(&data.finished) != num_cpus)
                        barrier();
        spin_unlock(&call_lock);
-
+       put_cpu_no_resched();
        return 0;
+}
+
+int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
+                       int wait)
+{
+       return smp_call_function_on_cpu(func, info, wait, cpu_online_map);
 }

 static void stop_this_cpu (void * dummy)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

[2.5][14/14] smp_call_function_on_cpu - x86_64

Post by Andi Klee » Sat, 15 Feb 2003 17:40:12



> One liner to fix num_cpus == 0 on SMP kernel w/ UP box

Shouldn't num_cpus be 1 in that case ?

-Andi
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

[2.5][14/14] smp_call_function_on_cpu - x86_64

Post by Zwane Mwaikamb » Sat, 15 Feb 2003 19:20:08




> > One liner to fix num_cpus == 0 on SMP kernel w/ UP box

> Shouldn't num_cpus be 1 in that case ?

We mask out current cpu first like so;

mask &= ~(1UL << smp_processor_id());
num_cpus = hweight(mask);
if (num_cpus == )
        return 0;

So really it's number of eligible IPI cpus

        Zwane
--
function.linuxpower.ca
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

1. [2.5][1/14] smp_call_function_on_cpu - generic definitions

Index: linux-2.5.60/include/linux/smp.h
===================================================================
RCS file: /build/cvsroot/linux-2.5.60/include/linux/smp.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 smp.h
--- linux-2.5.60/include/linux/smp.h    10 Feb 2003 22:17:13 -0000      1.1.1.1

                              int retry, int wait);

 /*
+ * Call a function on arbitrary processors encapsulated in a bitmask
+ */
+extern int smp_call_function_on_cpu (void (*func) (void *info), void *info,
+                               int wait, unsigned long mask);
+
+/*
  * True once the per process idle is forked
  */

 #define hard_smp_processor_id()                        0
 #define smp_threads_ready                      1
 #define smp_call_function(func,info,retry,wait)        ({ 0; })
+#define smp_call_function_on_cpu(func,info,wait,mask) ({ 0; })
 static inline void smp_send_reschedule(int cpu) { }
 static inline void smp_send_reschedule_all(void) { }
 #define cpu_online_map                         1
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

2. Promise eide4030plus disk accelerator compatibility ???

3. [2.5][8/14] smp_call_function_on_cpu - s390

4. Changing resolution?

5. [2.5][10/14] smp_call_function_on_cpu - sparc64

6. where is the ThinkPad info page now?

7. [2.5][4/14] smp_call_function_on_cpu - MIPS

8. OOPS in do_try_to_free_pages with VERY large software RAID array

9. [2.5][13/14] smp_call_function_on_cpu - UML

10. [2.5][6/14] smp_call_function_on_cpu - PPC32

11. [2.5][12/14] smp_call_function_on_cpu locking changes - Alpha

12. [2.5][3/14] smp_call_function_on_cpu - ia64