aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/rcupdate.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/rcupdate.h')
-rw-r--r--include/linux/rcupdate.h45
1 files changed, 36 insertions, 9 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index a005cac5e302..3024050c82a1 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -101,6 +101,11 @@ extern struct lockdep_map rcu_sched_lock_map;
101# define rcu_read_release_sched() \ 101# define rcu_read_release_sched() \
102 lock_release(&rcu_sched_lock_map, 1, _THIS_IP_) 102 lock_release(&rcu_sched_lock_map, 1, _THIS_IP_)
103 103
104static inline int debug_lockdep_rcu_enabled(void)
105{
106 return likely(rcu_scheduler_active && debug_locks);
107}
108
104/** 109/**
105 * rcu_read_lock_held - might we be in RCU read-side critical section? 110 * rcu_read_lock_held - might we be in RCU read-side critical section?
106 * 111 *
@@ -108,12 +113,14 @@ extern struct lockdep_map rcu_sched_lock_map;
108 * an RCU read-side critical section. In absence of CONFIG_PROVE_LOCKING, 113 * an RCU read-side critical section. In absence of CONFIG_PROVE_LOCKING,
109 * this assumes we are in an RCU read-side critical section unless it can 114 * this assumes we are in an RCU read-side critical section unless it can
110 * prove otherwise. 115 * prove otherwise.
116 *
117 * Check rcu_scheduler_active to prevent false positives during boot.
111 */ 118 */
112static inline int rcu_read_lock_held(void) 119static inline int rcu_read_lock_held(void)
113{ 120{
114 if (debug_locks) 121 if (!debug_lockdep_rcu_enabled())
115 return lock_is_held(&rcu_lock_map); 122 return 1;
116 return 1; 123 return lock_is_held(&rcu_lock_map);
117} 124}
118 125
119/** 126/**
@@ -123,12 +130,14 @@ static inline int rcu_read_lock_held(void)
123 * an RCU-bh read-side critical section. In absence of CONFIG_PROVE_LOCKING, 130 * an RCU-bh read-side critical section. In absence of CONFIG_PROVE_LOCKING,
124 * this assumes we are in an RCU-bh read-side critical section unless it can 131 * this assumes we are in an RCU-bh read-side critical section unless it can
125 * prove otherwise. 132 * prove otherwise.
133 *
134 * Check rcu_scheduler_active to prevent false positives during boot.
126 */ 135 */
127static inline int rcu_read_lock_bh_held(void) 136static inline int rcu_read_lock_bh_held(void)
128{ 137{
129 if (debug_locks) 138 if (!debug_lockdep_rcu_enabled())
130 return lock_is_held(&rcu_bh_lock_map); 139 return 1;
131 return 1; 140 return lock_is_held(&rcu_bh_lock_map);
132} 141}
133 142
134/** 143/**
@@ -139,15 +148,26 @@ static inline int rcu_read_lock_bh_held(void)
139 * this assumes we are in an RCU-sched read-side critical section unless it 148 * this assumes we are in an RCU-sched read-side critical section unless it
140 * can prove otherwise. Note that disabling of preemption (including 149 * can prove otherwise. Note that disabling of preemption (including
141 * disabling irqs) counts as an RCU-sched read-side critical section. 150 * disabling irqs) counts as an RCU-sched read-side critical section.
151 *
152 * Check rcu_scheduler_active to prevent false positives during boot.
142 */ 153 */
154#ifdef CONFIG_PREEMPT
143static inline int rcu_read_lock_sched_held(void) 155static inline int rcu_read_lock_sched_held(void)
144{ 156{
145 int lockdep_opinion = 0; 157 int lockdep_opinion = 0;
146 158
159 if (!debug_lockdep_rcu_enabled())
160 return 1;
147 if (debug_locks) 161 if (debug_locks)
148 lockdep_opinion = lock_is_held(&rcu_sched_lock_map); 162 lockdep_opinion = lock_is_held(&rcu_sched_lock_map);
149 return lockdep_opinion || preempt_count() != 0 || !rcu_scheduler_active; 163 return lockdep_opinion || preempt_count() != 0;
164}
165#else /* #ifdef CONFIG_PREEMPT */
166static inline int rcu_read_lock_sched_held(void)
167{
168 return 1;
150} 169}
170#endif /* #else #ifdef CONFIG_PREEMPT */
151 171
152#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ 172#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
153 173
@@ -168,10 +188,17 @@ static inline int rcu_read_lock_bh_held(void)
168 return 1; 188 return 1;
169} 189}
170 190
191#ifdef CONFIG_PREEMPT
171static inline int rcu_read_lock_sched_held(void) 192static inline int rcu_read_lock_sched_held(void)
172{ 193{
173 return preempt_count() != 0 || !rcu_scheduler_active; 194 return !rcu_scheduler_active || preempt_count() != 0;
195}
196#else /* #ifdef CONFIG_PREEMPT */
197static inline int rcu_read_lock_sched_held(void)
198{
199 return 1;
174} 200}
201#endif /* #else #ifdef CONFIG_PREEMPT */
175 202
176#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ 203#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
177 204
@@ -188,7 +215,7 @@ static inline int rcu_read_lock_sched_held(void)
188 */ 215 */
189#define rcu_dereference_check(p, c) \ 216#define rcu_dereference_check(p, c) \
190 ({ \ 217 ({ \
191 if (debug_locks && !(c)) \ 218 if (debug_lockdep_rcu_enabled() && !(c)) \
192 lockdep_rcu_dereference(__FILE__, __LINE__); \ 219 lockdep_rcu_dereference(__FILE__, __LINE__); \
193 rcu_dereference_raw(p); \ 220 rcu_dereference_raw(p); \
194 }) 221 })