aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorPaul E. McKenney <paul.mckenney@linaro.org>2012-03-27 19:02:08 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2012-05-02 17:43:23 -0400
commit616c310e83b872024271c915c1b9ab505b9efad9 (patch)
tree1339bc7b3bef920b4641a5af2f182e9dfa2a6632 /include/linux
parent66f75a5d028beaf67c931435fdc3e7823125730c (diff)
rcu: Move PREEMPT_RCU preemption to switch_to() invocation
Currently, PREEMPT_RCU readers are enqueued upon entry to the scheduler. This is inefficient because enqueuing is required only if there is a context switch, and entry to the scheduler does not guarantee a context switch. The commit therefore moves the enqueuing to immediately precede the call to switch_to() from the scheduler. Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Tested-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/rcupdate.h1
-rw-r--r--include/linux/rcutiny.h6
-rw-r--r--include/linux/sched.h10
3 files changed, 11 insertions, 6 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 20fb776a1d4a..bbfe7854a6a6 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -184,6 +184,7 @@ static inline int rcu_preempt_depth(void)
184/* Internal to kernel */ 184/* Internal to kernel */
185extern void rcu_sched_qs(int cpu); 185extern void rcu_sched_qs(int cpu);
186extern void rcu_bh_qs(int cpu); 186extern void rcu_bh_qs(int cpu);
187extern void rcu_preempt_note_context_switch(void);
187extern void rcu_check_callbacks(int cpu, int user); 188extern void rcu_check_callbacks(int cpu, int user);
188struct notifier_block; 189struct notifier_block;
189extern void rcu_idle_enter(void); 190extern void rcu_idle_enter(void);
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
index e93df77176d1..080b5bdda28e 100644
--- a/include/linux/rcutiny.h
+++ b/include/linux/rcutiny.h
@@ -87,10 +87,6 @@ static inline void kfree_call_rcu(struct rcu_head *head,
87 87
88#ifdef CONFIG_TINY_RCU 88#ifdef CONFIG_TINY_RCU
89 89
90static inline void rcu_preempt_note_context_switch(void)
91{
92}
93
94static inline void exit_rcu(void) 90static inline void exit_rcu(void)
95{ 91{
96} 92}
@@ -102,7 +98,6 @@ static inline int rcu_needs_cpu(int cpu)
102 98
103#else /* #ifdef CONFIG_TINY_RCU */ 99#else /* #ifdef CONFIG_TINY_RCU */
104 100
105void rcu_preempt_note_context_switch(void);
106extern void exit_rcu(void); 101extern void exit_rcu(void);
107int rcu_preempt_needs_cpu(void); 102int rcu_preempt_needs_cpu(void);
108 103
@@ -116,7 +111,6 @@ static inline int rcu_needs_cpu(int cpu)
116static inline void rcu_note_context_switch(int cpu) 111static inline void rcu_note_context_switch(int cpu)
117{ 112{
118 rcu_sched_qs(cpu); 113 rcu_sched_qs(cpu);
119 rcu_preempt_note_context_switch();
120} 114}
121 115
122/* 116/*
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 81a173c0897d..8f3fd945070f 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1905,12 +1905,22 @@ static inline void rcu_copy_process(struct task_struct *p)
1905 INIT_LIST_HEAD(&p->rcu_node_entry); 1905 INIT_LIST_HEAD(&p->rcu_node_entry);
1906} 1906}
1907 1907
1908static inline void rcu_switch_from(struct task_struct *prev)
1909{
1910 if (prev->rcu_read_lock_nesting != 0)
1911 rcu_preempt_note_context_switch();
1912}
1913
1908#else 1914#else
1909 1915
1910static inline void rcu_copy_process(struct task_struct *p) 1916static inline void rcu_copy_process(struct task_struct *p)
1911{ 1917{
1912} 1918}
1913 1919
1920static inline void rcu_switch_from(struct task_struct *prev)
1921{
1922}
1923
1914#endif 1924#endif
1915 1925
1916#ifdef CONFIG_SMP 1926#ifdef CONFIG_SMP