From: Xiantao Zhang <xiantao.zhang@xxxxxxxxx> Date: Wed, 12 Mar 2008 12:58:02 +0800 Subject: [PATCH] Implement smp_call_function_mask for ia64 This function provides more flexible interface for smp infrastructure. Signed-off-by: Xiantao Zhang <xiantao.zhang@xxxxxxxxx> --- arch/ia64/kernel/smp.c | 84 +++++++++++++++++++++++++++++++++++++---------- include/linux/smp.h | 3 ++ 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 4e446aa..5bb241f 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -213,6 +213,19 @@ send_IPI_allbutself (int op) * Called with preemption disabled. */ static inline void +send_IPI_mask(cpumask_t mask, int op) +{ + unsigned int cpu; + + for_each_cpu_mask(cpu, mask) { + send_IPI_single(cpu, op); + } +} + +/* + * Called with preemption disabled. + */ +static inline void send_IPI_all (int op) { int i; @@ -401,33 +414,36 @@ smp_call_function_single (int cpuid, void (*func) (void *info), void *info, int } EXPORT_SYMBOL(smp_call_function_single); -/* - * this function sends a 'generic call function' IPI to all other CPUs - * in the system. - */ - -/* - * [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. +/** + * smp_call_function_mask(): Run a function on a set of other CPUs. + * <mask> The set of cpus to run on. Must not include the current cpu. + * <func> The function to run. This must be fast and non-blocking. + * <info> An arbitrary pointer to pass to the function. + * <wait> If true, wait (atomically) until function + * has completed on other CPUs. * - * Does not return until remote CPUs are nearly ready to execute <func> or are or have - * executed. + * Returns 0 on success, else a negative status code. + * + * If @wait is true, then returns once @func has returned; otherwise + * it returns just before the target cpu calls @func. * * 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 (void (*func) (void *info), void *info, int nonatomic, int wait) +int smp_call_function_mask(cpumask_t mask, + void (*func)(void *), void *info, + int wait) { struct call_data_struct data; + cpumask_t allbutself; int cpus; spin_lock(&call_lock); - cpus = num_online_cpus() - 1; + allbutself = cpu_online_map; + cpu_clear(smp_processor_id(), allbutself); + + cpus_and(mask, mask, allbutself); + cpus = cpus_weight(mask); if (!cpus) { spin_unlock(&call_lock); return 0; @@ -445,7 +461,12 @@ smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wai call_data = &data; mb(); /* ensure store to call_data precedes setting of IPI_CALL_FUNC */ - send_IPI_allbutself(IPI_CALL_FUNC); + + /* Send a message to other CPUs */ + if (cpus_equal(mask, allbutself)) + send_IPI_allbutself(IPI_CALL_FUNC); + else + send_IPI_mask(mask, IPI_CALL_FUNC); /* Wait for response */ while (atomic_read(&data.started) != cpus) @@ -458,6 +479,33 @@ smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wai spin_unlock(&call_lock); return 0; + +} +EXPORT_SYMBOL(smp_call_function_mask); + +/* + * this function sends a 'generic call function' IPI to all other CPUs + * in the system. + */ + +/* + * [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. + * + * 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 (void (*func) (void *info), void *info, int nonatomic, int wait) +{ + return smp_call_function_mask(cpu_online_map, func, info, wait); } EXPORT_SYMBOL(smp_call_function); diff --git a/include/linux/smp.h b/include/linux/smp.h index 55232cc..b71820b 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -56,6 +56,9 @@ int smp_call_function(void(*func)(void *info), void *info, int retry, int wait); int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, int retry, int wait); +int smp_call_function_mask(cpumask_t mask, + void (*func)(void *), void *info, + int wait); /* * Call a function on all processors -- 1.5.2
Attachment:
0001-Implement-smp_call_function_mask-for-ia64.patch
Description: 0001-Implement-smp_call_function_mask-for-ia64.patch
![]() |