Commit 2439b696cb5303f1eeb6aeebcee19e0056c3dd6e

Authored by Paul E. McKenney
1 parent 7807acdb6b

rcu: Shrink TINY_RCU by moving exit_rcu()

Now that TINY_PREEMPT_RCU is no more, exit_rcu() is always an empty
function.  But if TINY_RCU is going to have an empty function, it should
be in include/linux/rcutiny.h, where it does not bloat the kernel.
This commit therefore moves exit_rcu() out of kernel/rcupdate.c to
kernel/rcutree_plugin.h, and places a static inline empty function in
include/linux/rcutiny.h in order to shrink TINY_RCU a bit.

Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>

Showing 5 changed files with 33 additions and 27 deletions Side-by-side Diff

include/linux/rcupdate.h
... ... @@ -240,8 +240,6 @@
240 240 struct task_struct *next) { }
241 241 #endif /* CONFIG_RCU_USER_QS */
242 242  
243   -extern void exit_rcu(void);
244   -
245 243 /**
246 244 * RCU_NONIDLE - Indicate idle-loop code that needs RCU readers
247 245 * @a: Code that RCU needs to pay attention to.
include/linux/rcutiny.h
... ... @@ -119,6 +119,10 @@
119 119 {
120 120 }
121 121  
  122 +static inline void exit_rcu(void)
  123 +{
  124 +}
  125 +
122 126 #ifdef CONFIG_DEBUG_LOCK_ALLOC
123 127 extern int rcu_scheduler_active __read_mostly;
124 128 extern void rcu_scheduler_starting(void);
include/linux/rcutree.h
... ... @@ -85,6 +85,8 @@
85 85 extern void rcu_bh_force_quiescent_state(void);
86 86 extern void rcu_sched_force_quiescent_state(void);
87 87  
  88 +extern void exit_rcu(void);
  89 +
88 90 extern void rcu_scheduler_starting(void);
89 91 extern int rcu_scheduler_active __read_mostly;
90 92  
... ... @@ -104,31 +104,7 @@
104 104 }
105 105 EXPORT_SYMBOL_GPL(__rcu_read_unlock);
106 106  
107   -/*
108   - * Check for a task exiting while in a preemptible-RCU read-side
109   - * critical section, clean up if so. No need to issue warnings,
110   - * as debug_check_no_locks_held() already does this if lockdep
111   - * is enabled.
112   - */
113   -void exit_rcu(void)
114   -{
115   - struct task_struct *t = current;
116   -
117   - if (likely(list_empty(&current->rcu_node_entry)))
118   - return;
119   - t->rcu_read_lock_nesting = 1;
120   - barrier();
121   - t->rcu_read_unlock_special = RCU_READ_UNLOCK_BLOCKED;
122   - __rcu_read_unlock();
123   -}
124   -
125   -#else /* #ifdef CONFIG_PREEMPT_RCU */
126   -
127   -void exit_rcu(void)
128   -{
129   -}
130   -
131   -#endif /* #else #ifdef CONFIG_PREEMPT_RCU */
  107 +#endif /* #ifdef CONFIG_PREEMPT_RCU */
132 108  
133 109 #ifdef CONFIG_DEBUG_LOCK_ALLOC
134 110 static struct lock_class_key rcu_lock_key;
kernel/rcutree_plugin.h
... ... @@ -932,6 +932,24 @@
932 932 rcu_init_one(&rcu_preempt_state, &rcu_preempt_data);
933 933 }
934 934  
  935 +/*
  936 + * Check for a task exiting while in a preemptible-RCU read-side
  937 + * critical section, clean up if so. No need to issue warnings,
  938 + * as debug_check_no_locks_held() already does this if lockdep
  939 + * is enabled.
  940 + */
  941 +void exit_rcu(void)
  942 +{
  943 + struct task_struct *t = current;
  944 +
  945 + if (likely(list_empty(&current->rcu_node_entry)))
  946 + return;
  947 + t->rcu_read_lock_nesting = 1;
  948 + barrier();
  949 + t->rcu_read_unlock_special = RCU_READ_UNLOCK_BLOCKED;
  950 + __rcu_read_unlock();
  951 +}
  952 +
935 953 #else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
936 954  
937 955 static struct rcu_state *rcu_state = &rcu_sched_state;
... ... @@ -1097,6 +1115,14 @@
1097 1115 * Because preemptible RCU does not exist, it need not be initialized.
1098 1116 */
1099 1117 static void __init __rcu_init_preempt(void)
  1118 +{
  1119 +}
  1120 +
  1121 +/*
  1122 + * Because preemptible RCU does not exist, tasks cannot possibly exit
  1123 + * while in preemptible RCU read-side critical sections.
  1124 + */
  1125 +void exit_rcu(void)
1100 1126 {
1101 1127 }
1102 1128