aboutsummaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorGilad Ben-Yossef <[email protected]>2012-03-28 14:42:43 -0700
committerLinus Torvalds <[email protected]>2012-03-28 17:14:35 -0700
commitb3a7e98e024ffa9f7e4554dd720c508015c4a831 (patch)
tree50c09e1a47418ba4bb55b11f756bf4d99cf76123 /include/linux
parent3fc498f165304dc913f1d13b5ac9ab4c758ee7ab (diff)
smp: add func to IPI cpus based on parameter func
Add the on_each_cpu_cond() function that wraps on_each_cpu_mask() and calculates the cpumask of cpus to IPI by calling a function supplied as a parameter in order to determine whether to IPI each specific cpu. The function works around allocation failure of cpumask variable in CONFIG_CPUMASK_OFFSTACK=y by itereating over cpus sending an IPI a time via smp_call_function_single(). The function is useful since it allows to seperate the specific code that decided in each case whether to IPI a specific cpu for a specific request from the common boilerplate code of handling creating the mask, handling failures etc. [[email protected]: s/gfpflags/gfp_flags/] [[email protected]: avoid double-evaluation of `info' (per Michal), parenthesise evaluation of `cond_func'] [[email protected]: s/CPU/CPUs, use all 80 cols in comment] Signed-off-by: Gilad Ben-Yossef <[email protected]> Cc: Chris Metcalf <[email protected]> Cc: Christoph Lameter <[email protected]> Acked-by: Peter Zijlstra <[email protected]> Cc: Frederic Weisbecker <[email protected]> Cc: Russell King <[email protected]> Cc: Pekka Enberg <[email protected]> Cc: Matt Mackall <[email protected]> Cc: Sasha Levin <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Alexander Viro <[email protected]> Cc: Avi Kivity <[email protected]> Acked-by: Michal Nazarewicz <[email protected]> Cc: Kosaki Motohiro <[email protected]> Cc: Milton Miller <[email protected]> Reviewed-by: "Srivatsa S. Bhat" <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/smp.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/include/linux/smp.h b/include/linux/smp.h
index d0adb7898d54..10530d92c04b 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -109,6 +109,15 @@ void on_each_cpu_mask(const struct cpumask *mask, smp_call_func_t func,
void *info, bool wait);
/*
+ * Call a function on each processor for which the supplied function
+ * cond_func returns a positive value. This may include the local
+ * processor.
+ */
+void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info),
+ smp_call_func_t func, void *info, bool wait,
+ gfp_t gfp_flags);
+
+/*
* Mark the boot cpu "online" so that it can call console drivers in
* printk() and can access its per-cpu storage.
*/
@@ -153,6 +162,21 @@ static inline int up_smp_call_function(smp_call_func_t func, void *info)
local_irq_enable(); \
} \
} while (0)
+/*
+ * Preemption is disabled here to make sure the cond_func is called under the
+ * same condtions in UP and SMP.
+ */
+#define on_each_cpu_cond(cond_func, func, info, wait, gfp_flags)\
+ do { \
+ void *__info = (info); \
+ preempt_disable(); \
+ if ((cond_func)(0, __info)) { \
+ local_irq_disable(); \
+ (func)(__info); \
+ local_irq_enable(); \
+ } \
+ preempt_enable(); \
+ } while (0)
static inline void smp_send_reschedule(int cpu) { }
#define num_booting_cpus() 1