diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-03 17:32:04 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-03 17:32:04 -0500 |
| commit | b24746c7be75384d182845375c96433d713981bb (patch) | |
| tree | fdb0371d9e59c94e18c946a88c4aa3bcfa4af9b1 /kernel | |
| parent | f41bf2ab998daaa2ac27348d5813e0ae21c57ded (diff) | |
| parent | a682604838763981613e42015cd0e39f2989d6bb (diff) | |
Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
rcu: Teach RCU that idle task is not quiscent state at boot
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/rcuclassic.c | 4 | ||||
| -rw-r--r-- | kernel/rcupdate.c | 12 | ||||
| -rw-r--r-- | kernel/rcupreempt.c | 3 | ||||
| -rw-r--r-- | kernel/rcutree.c | 4 |
4 files changed, 19 insertions, 4 deletions
diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c index bd5a9003497c..654c640a6b9c 100644 --- a/kernel/rcuclassic.c +++ b/kernel/rcuclassic.c | |||
| @@ -679,8 +679,8 @@ int rcu_needs_cpu(int cpu) | |||
| 679 | void rcu_check_callbacks(int cpu, int user) | 679 | void rcu_check_callbacks(int cpu, int user) |
| 680 | { | 680 | { |
| 681 | if (user || | 681 | if (user || |
| 682 | (idle_cpu(cpu) && !in_softirq() && | 682 | (idle_cpu(cpu) && rcu_scheduler_active && |
| 683 | hardirq_count() <= (1 << HARDIRQ_SHIFT))) { | 683 | !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) { |
| 684 | 684 | ||
| 685 | /* | 685 | /* |
| 686 | * Get here if this CPU took its interrupt from user | 686 | * Get here if this CPU took its interrupt from user |
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index d92a76a881aa..cae8a059cf47 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <linux/cpu.h> | 44 | #include <linux/cpu.h> |
| 45 | #include <linux/mutex.h> | 45 | #include <linux/mutex.h> |
| 46 | #include <linux/module.h> | 46 | #include <linux/module.h> |
| 47 | #include <linux/kernel_stat.h> | ||
| 47 | 48 | ||
| 48 | enum rcu_barrier { | 49 | enum rcu_barrier { |
| 49 | RCU_BARRIER_STD, | 50 | RCU_BARRIER_STD, |
| @@ -55,6 +56,7 @@ static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL}; | |||
| 55 | static atomic_t rcu_barrier_cpu_count; | 56 | static atomic_t rcu_barrier_cpu_count; |
| 56 | static DEFINE_MUTEX(rcu_barrier_mutex); | 57 | static DEFINE_MUTEX(rcu_barrier_mutex); |
| 57 | static struct completion rcu_barrier_completion; | 58 | static struct completion rcu_barrier_completion; |
| 59 | int rcu_scheduler_active __read_mostly; | ||
| 58 | 60 | ||
| 59 | /* | 61 | /* |
| 60 | * Awaken the corresponding synchronize_rcu() instance now that a | 62 | * Awaken the corresponding synchronize_rcu() instance now that a |
| @@ -80,6 +82,10 @@ void wakeme_after_rcu(struct rcu_head *head) | |||
| 80 | void synchronize_rcu(void) | 82 | void synchronize_rcu(void) |
| 81 | { | 83 | { |
| 82 | struct rcu_synchronize rcu; | 84 | struct rcu_synchronize rcu; |
| 85 | |||
| 86 | if (rcu_blocking_is_gp()) | ||
| 87 | return; | ||
| 88 | |||
| 83 | init_completion(&rcu.completion); | 89 | init_completion(&rcu.completion); |
| 84 | /* Will wake me after RCU finished. */ | 90 | /* Will wake me after RCU finished. */ |
| 85 | call_rcu(&rcu.head, wakeme_after_rcu); | 91 | call_rcu(&rcu.head, wakeme_after_rcu); |
| @@ -175,3 +181,9 @@ void __init rcu_init(void) | |||
| 175 | __rcu_init(); | 181 | __rcu_init(); |
| 176 | } | 182 | } |
| 177 | 183 | ||
| 184 | void rcu_scheduler_starting(void) | ||
| 185 | { | ||
| 186 | WARN_ON(num_online_cpus() != 1); | ||
| 187 | WARN_ON(nr_context_switches() > 0); | ||
| 188 | rcu_scheduler_active = 1; | ||
| 189 | } | ||
diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index 33cfc50781f9..5d59e850fb71 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c | |||
| @@ -1181,6 +1181,9 @@ void __synchronize_sched(void) | |||
| 1181 | { | 1181 | { |
| 1182 | struct rcu_synchronize rcu; | 1182 | struct rcu_synchronize rcu; |
| 1183 | 1183 | ||
| 1184 | if (num_online_cpus() == 1) | ||
| 1185 | return; /* blocking is gp if only one CPU! */ | ||
| 1186 | |||
| 1184 | init_completion(&rcu.completion); | 1187 | init_completion(&rcu.completion); |
| 1185 | /* Will wake me after RCU finished. */ | 1188 | /* Will wake me after RCU finished. */ |
| 1186 | call_rcu_sched(&rcu.head, wakeme_after_rcu); | 1189 | call_rcu_sched(&rcu.head, wakeme_after_rcu); |
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index b2fd602a6f6f..97ce31579ec0 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
| @@ -948,8 +948,8 @@ static void rcu_do_batch(struct rcu_data *rdp) | |||
| 948 | void rcu_check_callbacks(int cpu, int user) | 948 | void rcu_check_callbacks(int cpu, int user) |
| 949 | { | 949 | { |
| 950 | if (user || | 950 | if (user || |
| 951 | (idle_cpu(cpu) && !in_softirq() && | 951 | (idle_cpu(cpu) && rcu_scheduler_active && |
| 952 | hardirq_count() <= (1 << HARDIRQ_SHIFT))) { | 952 | !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) { |
| 953 | 953 | ||
| 954 | /* | 954 | /* |
| 955 | * Get here if this CPU took its interrupt from user | 955 | * Get here if this CPU took its interrupt from user |
