Name: on_one_cpu function Author: Rusty Russell Status: Booted on 2.6.5 Similar to on_each_cpu, this implements on_one_cpu. For archs which don't do it natively, it's implemented in terms of smp_call_function(). diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .21074-linux-2.6.5/include/linux/smp.h .21074-linux-2.6.5.updated/include/linux/smp.h diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .23974-linux-2.6.7-rc2/include/linux/smp.h .23974-linux-2.6.7-rc2.updated/include/linux/smp.h --- .23974-linux-2.6.7-rc2/include/linux/smp.h 2004-03-12 07:57:26.000000000 +1100 +++ .23974-linux-2.6.7-rc2.updated/include/linux/smp.h 2004-05-31 12:05:43.000000000 +1000 @@ -8,6 +8,10 @@ #include +#define get_cpu() ({ preempt_disable(); smp_processor_id(); }) +#define put_cpu() preempt_enable() +#define put_cpu_no_resched() preempt_enable_no_resched() + #ifdef CONFIG_SMP #include @@ -69,6 +73,11 @@ static inline int on_each_cpu(void (*fun return ret; } +#ifndef __HAVE_ARCH_ON_ONE_CPU +extern int on_one_cpu(unsigned cpu, void (*func)(void *info), void *info); +#endif + + /* * True once the per process idle is forked */ @@ -101,14 +110,11 @@ void smp_prepare_boot_cpu(void); #define smp_threads_ready 1 #define smp_call_function(func,info,retry,wait) ({ 0; }) #define on_each_cpu(func,info,retry,wait) ({ func(info); 0; }) +#define on_one_cpu(cpu,func,info) ({ func(info); 0; }) static inline void smp_send_reschedule(int cpu) { } #define num_booting_cpus() 1 #define smp_prepare_boot_cpu() do {} while (0) #endif /* !SMP */ -#define get_cpu() ({ preempt_disable(); smp_processor_id(); }) -#define put_cpu() preempt_enable() -#define put_cpu_no_resched() preempt_enable_no_resched() - #endif /* __LINUX_SMP_H */ diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .23974-linux-2.6.7-rc2/kernel/sched.c .23974-linux-2.6.7-rc2.updated/kernel/sched.c --- .23974-linux-2.6.7-rc2/kernel/sched.c 2004-05-31 09:57:40.000000000 +1000 +++ .23974-linux-2.6.7-rc2.updated/kernel/sched.c 2004-05-31 12:06:40.000000000 +1000 @@ -671,7 +671,39 @@ static inline unsigned long target_load( return max(rq->cpu_load, load_now); } -#endif +#ifndef __HAVE_ARCH_ON_ONE_CPU +struct which_cpu +{ + unsigned int cpu; + void (*func)(void *info); + void *info; +}; + +static void maybe_on_cpu(void *_which) +{ + struct which_cpu *which = _which; + + if (smp_processor_id() == which->cpu) + which->func(which->info); +} + +static inline int on_one_cpu(unsigned cpu, + void (*func)(void *info), void *info) +{ + int ret; + + if (cpu == get_cpu()) { + func(info); + ret = 0; + } else { + struct which_cpu which = { cpu, func, info }; + ret = smp_call_function(maybe_on_cpu, &which, 1, 1); + } + put_cpu(); + return ret; +} +#endif /* __HAVE_ARCH_ON_ONE_CPU */ +#endif /* CONFIG_SMP */ /* * wake_idle() is useful especially on SMT architectures to wake a