mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-01 20:14:08 +00:00
smp: quit unconditionally enabling irq in on_each_cpu_mask and on_each_cpu_cond
As in commit f21afc25f9
("smp.h: Use local_irq_{save,restore}() in
!SMP version of on_each_cpu()"), we don't want to enable irqs if they
are not already enabled. There are currently no known problematical
callers of these functions, but since it is a known failure pattern, we
preemptively fix them.
Since they are not trivial functions, make them non-inline by moving
them to up.c. This also makes it so we don't have to fix #include
dependancies for preempt_{disable,enable}.
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
c14c338cb0
commit
fa688207c9
2 changed files with 55 additions and 46 deletions
|
@ -29,6 +29,22 @@ extern unsigned int total_cpus;
|
||||||
int smp_call_function_single(int cpuid, smp_call_func_t func, void *info,
|
int smp_call_function_single(int cpuid, smp_call_func_t func, void *info,
|
||||||
int wait);
|
int wait);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call a function on processors specified by mask, which might include
|
||||||
|
* the local one.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
|
||||||
#include <linux/preempt.h>
|
#include <linux/preempt.h>
|
||||||
|
@ -100,22 +116,6 @@ static inline void call_function_init(void) { }
|
||||||
*/
|
*/
|
||||||
int on_each_cpu(smp_call_func_t func, void *info, int wait);
|
int on_each_cpu(smp_call_func_t func, void *info, int wait);
|
||||||
|
|
||||||
/*
|
|
||||||
* Call a function on processors specified by mask, which might include
|
|
||||||
* the local one.
|
|
||||||
*/
|
|
||||||
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
|
* Mark the boot cpu "online" so that it can call console drivers in
|
||||||
* printk() and can access its per-cpu storage.
|
* printk() and can access its per-cpu storage.
|
||||||
|
@ -151,36 +151,6 @@ static inline int on_each_cpu(smp_call_func_t func, void *info, int wait)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Note we still need to test the mask even for UP
|
|
||||||
* because we actually can get an empty mask from
|
|
||||||
* code that on SMP might call us without the local
|
|
||||||
* CPU in the mask.
|
|
||||||
*/
|
|
||||||
#define on_each_cpu_mask(mask, func, info, wait) \
|
|
||||||
do { \
|
|
||||||
if (cpumask_test_cpu(0, (mask))) { \
|
|
||||||
local_irq_disable(); \
|
|
||||||
(func)(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) { }
|
static inline void smp_send_reschedule(int cpu) { }
|
||||||
#define smp_prepare_boot_cpu() do {} while (0)
|
#define smp_prepare_boot_cpu() do {} while (0)
|
||||||
#define smp_call_function_many(mask, func, info, wait) \
|
#define smp_call_function_many(mask, func, info, wait) \
|
||||||
|
|
39
kernel/up.c
39
kernel/up.c
|
@ -19,3 +19,42 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(smp_call_function_single);
|
EXPORT_SYMBOL(smp_call_function_single);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note we still need to test the mask even for UP
|
||||||
|
* because we actually can get an empty mask from
|
||||||
|
* code that on SMP might call us without the local
|
||||||
|
* CPU in the mask.
|
||||||
|
*/
|
||||||
|
void on_each_cpu_mask(const struct cpumask *mask,
|
||||||
|
smp_call_func_t func, void *info, bool wait)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (cpumask_test_cpu(0, mask)) {
|
||||||
|
local_irq_save(flags);
|
||||||
|
func(info);
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(on_each_cpu_mask);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Preemption is disabled here to make sure the cond_func is called under the
|
||||||
|
* same condtions in UP and SMP.
|
||||||
|
*/
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
preempt_disable();
|
||||||
|
if (cond_func(0, info)) {
|
||||||
|
local_irq_save(flags);
|
||||||
|
func(info);
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
preempt_enable();
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(on_each_cpu_cond);
|
||||||
|
|
Loading…
Add table
Reference in a new issue