diff options
author | Ingo Molnar <mingo@kernel.org> | 2012-09-27 08:09:38 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-09-27 08:09:38 +0200 |
commit | fa34da708cbe1e2d9a2ee7fc68ea8fccbf095d12 (patch) | |
tree | b20795decb064af75aae8f9f6af77806b1a4769a /kernel/sched/core.c | |
parent | a9b86fab4b0a36fc4cd2712a07259c2c0e769742 (diff) | |
parent | cb349ca95407cbc11424d5e9fc7c8e700709041b (diff) |
Merge branch 'rcu/idle' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into core/rcu
Pull the RCU adaptive-idle feature from Paul E. McKenney:
"This series adds RCU APIs that allow non-idle tasks to
enter RCU idle mode and provides x86 code to make use of them, allowing
RCU to treat user-mode execution as an extended quiescent state when the
new RCU_USER_QS kernel configuration parameter is specified. Work is
in progress to port this to a few other architectures, but is not part
of this series."
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r-- | kernel/sched/core.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 1a48cdbc8631..3c4dec0594d6 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2081,6 +2081,7 @@ context_switch(struct rq *rq, struct task_struct *prev, #endif /* Here we just switch the register state and the stack. */ + rcu_switch(prev, next); switch_to(prev, next, prev); barrier(); @@ -3468,6 +3469,21 @@ asmlinkage void __sched schedule(void) } EXPORT_SYMBOL(schedule); +#ifdef CONFIG_RCU_USER_QS +asmlinkage void __sched schedule_user(void) +{ + /* + * If we come here after a random call to set_need_resched(), + * or we have been woken up remotely but the IPI has not yet arrived, + * we haven't yet exited the RCU idle mode. Do it here manually until + * we find a better solution. + */ + rcu_user_exit(); + schedule(); + rcu_user_enter(); +} +#endif + /** * schedule_preempt_disabled - called with preemption disabled * @@ -3569,6 +3585,7 @@ asmlinkage void __sched preempt_schedule_irq(void) /* Catch callers which need to be fixed */ BUG_ON(ti->preempt_count || !irqs_disabled()); + rcu_user_exit(); do { add_preempt_count(PREEMPT_ACTIVE); local_irq_enable(); |