Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
srcu.h
Go to the documentation of this file.
1 /*
2  * Sleepable Read-Copy Update mechanism for mutual exclusion
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  * Copyright (C) IBM Corporation, 2006
19  *
20  * Author: Paul McKenney <[email protected]>
21  *
22  * For detailed explanation of Read-Copy Update mechanism see -
23  * Documentation/RCU/ *.txt
24  *
25  */
26 
27 #ifndef _LINUX_SRCU_H
28 #define _LINUX_SRCU_H
29 
30 #include <linux/mutex.h>
31 #include <linux/rcupdate.h>
32 #include <linux/workqueue.h>
33 
35  unsigned long c[2];
36  unsigned long seq[2];
37 };
38 
39 struct rcu_batch {
40  struct rcu_head *head, **tail;
41 };
42 
43 struct srcu_struct {
44  unsigned completed;
46  spinlock_t queue_lock; /* protect ->batch_queue, ->running */
47  bool running;
48  /* callbacks just queued */
50  /* callbacks try to do the first check_zero */
52  /* callbacks done with the first check_zero and the flip */
56 #ifdef CONFIG_DEBUG_LOCK_ALLOC
57  struct lockdep_map dep_map;
58 #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
59 };
60 
61 #ifdef CONFIG_DEBUG_LOCK_ALLOC
62 
63 int __init_srcu_struct(struct srcu_struct *sp, const char *name,
64  struct lock_class_key *key);
65 
66 #define init_srcu_struct(sp) \
67 ({ \
68  static struct lock_class_key __srcu_key; \
69  \
70  __init_srcu_struct((sp), #sp, &__srcu_key); \
71 })
72 
73 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
74 
75 int init_srcu_struct(struct srcu_struct *sp);
76 
77 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
78 
96 void call_srcu(struct srcu_struct *sp, struct rcu_head *head,
97  void (*func)(struct rcu_head *head));
98 
99 void cleanup_srcu_struct(struct srcu_struct *sp);
100 int __srcu_read_lock(struct srcu_struct *sp) __acquires(sp);
101 void __srcu_read_unlock(struct srcu_struct *sp, int idx) __releases(sp);
102 void synchronize_srcu(struct srcu_struct *sp);
103 void synchronize_srcu_expedited(struct srcu_struct *sp);
104 long srcu_batches_completed(struct srcu_struct *sp);
105 void srcu_barrier(struct srcu_struct *sp);
106 
107 #ifdef CONFIG_DEBUG_LOCK_ALLOC
108 
136 static inline int srcu_read_lock_held(struct srcu_struct *sp)
137 {
138  if (!debug_lockdep_rcu_enabled())
139  return 1;
140  if (rcu_is_cpu_idle())
141  return 0;
142  if (!rcu_lockdep_current_cpu_online())
143  return 0;
144  return lock_is_held(&sp->dep_map);
145 }
146 
147 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
148 
149 static inline int srcu_read_lock_held(struct srcu_struct *sp)
150 {
151  return 1;
152 }
153 
154 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
155 
168 #define srcu_dereference_check(p, sp, c) \
169  __rcu_dereference_check((p), srcu_read_lock_held(sp) || (c), __rcu)
170 
181 #define srcu_dereference(p, sp) srcu_dereference_check((p), (sp), 0)
182 
200 static inline int srcu_read_lock(struct srcu_struct *sp) __acquires(sp)
201 {
202  int retval = __srcu_read_lock(sp);
203 
204  rcu_lock_acquire(&(sp)->dep_map);
206  "srcu_read_lock() used illegally while idle");
207  return retval;
208 }
209 
217 static inline void srcu_read_unlock(struct srcu_struct *sp, int idx)
218  __releases(sp)
219 {
221  "srcu_read_unlock() used illegally while idle");
222  rcu_lock_release(&(sp)->dep_map);
223  __srcu_read_unlock(sp, idx);
224 }
225 
241 static inline int srcu_read_lock_raw(struct srcu_struct *sp)
242 {
243  unsigned long flags;
244  int ret;
245 
246  local_irq_save(flags);
247  ret = __srcu_read_lock(sp);
248  local_irq_restore(flags);
249  return ret;
250 }
251 
260 static inline void srcu_read_unlock_raw(struct srcu_struct *sp, int idx)
261 {
262  unsigned long flags;
263 
264  local_irq_save(flags);
265  __srcu_read_unlock(sp, idx);
266  local_irq_restore(flags);
267 }
268 
269 #endif