aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2011-05-27 01:14:36 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2011-09-29 00:36:42 -0400
commit2c42818e962e2858334bf45bfc56662b3752df34 (patch)
tree192364123c9aeeab282c53168e51eddece9d8be4 /include
parentf039d1f1884b2fe9c13d28f59d8330f0b0518fc4 (diff)
rcu: Abstract common code for RCU grace-period-wait primitives
Pull the code that waits for an RCU grace period into a single function, which is then called by synchronize_rcu() and friends in the case of TREE_RCU and TREE_PREEMPT_RCU, and from rcu_barrier() and friends in the case of TINY_RCU and TINY_PREEMPT_RCU. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/rcupdate.h130
-rw-r--r--include/linux/rcutiny.h16
-rw-r--r--include/linux/rcutree.h2
3 files changed, 90 insertions, 58 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 87bd390df73..ae5327de41a 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -66,11 +66,73 @@ static inline void rcutorture_record_progress(unsigned long vernum)
66#define ULONG_CMP_LT(a, b) (ULONG_MAX / 2 < (a) - (b)) 66#define ULONG_CMP_LT(a, b) (ULONG_MAX / 2 < (a) - (b))
67 67
68/* Exported common interfaces */ 68/* Exported common interfaces */
69
70#ifdef CONFIG_PREEMPT_RCU
71
72/**
73 * call_rcu() - Queue an RCU callback for invocation after a grace period.
74 * @head: structure to be used for queueing the RCU updates.
75 * @func: actual callback function to be invoked after the grace period
76 *
77 * The callback function will be invoked some time after a full grace
78 * period elapses, in other words after all pre-existing RCU read-side
79 * critical sections have completed. However, the callback function
80 * might well execute concurrently with RCU read-side critical sections
81 * that started after call_rcu() was invoked. RCU read-side critical
82 * sections are delimited by rcu_read_lock() and rcu_read_unlock(),
83 * and may be nested.
84 */
85extern void call_rcu(struct rcu_head *head,
86 void (*func)(struct rcu_head *head));
87
88#else /* #ifdef CONFIG_PREEMPT_RCU */
89
90/* In classic RCU, call_rcu() is just call_rcu_sched(). */
91#define call_rcu call_rcu_sched
92
93#endif /* #else #ifdef CONFIG_PREEMPT_RCU */
94
95/**
96 * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period.
97 * @head: structure to be used for queueing the RCU updates.
98 * @func: actual callback function to be invoked after the grace period
99 *
100 * The callback function will be invoked some time after a full grace
101 * period elapses, in other words after all currently executing RCU
102 * read-side critical sections have completed. call_rcu_bh() assumes
103 * that the read-side critical sections end on completion of a softirq
104 * handler. This means that read-side critical sections in process
105 * context must not be interrupted by softirqs. This interface is to be
106 * used when most of the read-side critical sections are in softirq context.
107 * RCU read-side critical sections are delimited by :
108 * - rcu_read_lock() and rcu_read_unlock(), if in interrupt context.
109 * OR
110 * - rcu_read_lock_bh() and rcu_read_unlock_bh(), if in process context.
111 * These may be nested.
112 */
113extern void call_rcu_bh(struct rcu_head *head,
114 void (*func)(struct rcu_head *head));
115
116/**
117 * call_rcu_sched() - Queue an RCU for invocation after sched grace period.
118 * @head: structure to be used for queueing the RCU updates.
119 * @func: actual callback function to be invoked after the grace period
120 *
121 * The callback function will be invoked some time after a full grace
122 * period elapses, in other words after all currently executing RCU
123 * read-side critical sections have completed. call_rcu_sched() assumes
124 * that the read-side critical sections end on enabling of preemption
125 * or on voluntary preemption.
126 * RCU read-side critical sections are delimited by :
127 * - rcu_read_lock_sched() and rcu_read_unlock_sched(),
128 * OR
129 * anything that disables preemption.
130 * These may be nested.
131 */
69extern void call_rcu_sched(struct rcu_head *head, 132extern void call_rcu_sched(struct rcu_head *head,
70 void (*func)(struct rcu_head *rcu)); 133 void (*func)(struct rcu_head *rcu));
134
71extern void synchronize_sched(void); 135extern void synchronize_sched(void);
72extern void rcu_barrier_bh(void);
73extern void rcu_barrier_sched(void);
74 136
75static inline void __rcu_read_lock_bh(void) 137static inline void __rcu_read_lock_bh(void)
76{ 138{
@@ -143,6 +205,15 @@ static inline void rcu_exit_nohz(void)
143 205
144#endif /* #else #ifdef CONFIG_NO_HZ */ 206#endif /* #else #ifdef CONFIG_NO_HZ */
145 207
208/*
209 * Infrastructure to implement the synchronize_() primitives in
210 * TREE_RCU and rcu_barrier_() primitives in TINY_RCU.
211 */
212
213typedef void call_rcu_func_t(struct rcu_head *head,
214 void (*func)(struct rcu_head *head));
215void wait_rcu_gp(call_rcu_func_t crf);
216
146#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) 217#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
147#include <linux/rcutree.h> 218#include <linux/rcutree.h>
148#elif defined(CONFIG_TINY_RCU) || defined(CONFIG_TINY_PREEMPT_RCU) 219#elif defined(CONFIG_TINY_RCU) || defined(CONFIG_TINY_PREEMPT_RCU)
@@ -723,61 +794,6 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
723#define RCU_INIT_POINTER(p, v) \ 794#define RCU_INIT_POINTER(p, v) \
724 p = (typeof(*v) __force __rcu *)(v) 795 p = (typeof(*v) __force __rcu *)(v)
725 796
726/* Infrastructure to implement the synchronize_() primitives. */
727
728struct rcu_synchronize {
729 struct rcu_head head;
730 struct completion completion;
731};
732
733extern void wakeme_after_rcu(struct rcu_head *head);
734
735#ifdef CONFIG_PREEMPT_RCU
736
737/**
738 * call_rcu() - Queue an RCU callback for invocation after a grace period.
739 * @head: structure to be used for queueing the RCU updates.
740 * @func: actual callback function to be invoked after the grace period
741 *
742 * The callback function will be invoked some time after a full grace
743 * period elapses, in other words after all pre-existing RCU read-side
744 * critical sections have completed. However, the callback function
745 * might well execute concurrently with RCU read-side critical sections
746 * that started after call_rcu() was invoked. RCU read-side critical
747 * sections are delimited by rcu_read_lock() and rcu_read_unlock(),
748 * and may be nested.
749 */
750extern void call_rcu(struct rcu_head *head,
751 void (*func)(struct rcu_head *head));
752
753#else /* #ifdef CONFIG_PREEMPT_RCU */
754
755/* In classic RCU, call_rcu() is just call_rcu_sched(). */
756#define call_rcu call_rcu_sched
757
758#endif /* #else #ifdef CONFIG_PREEMPT_RCU */
759
760/**
761 * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period.
762 * @head: structure to be used for queueing the RCU updates.
763 * @func: actual callback function to be invoked after the grace period
764 *
765 * The callback function will be invoked some time after a full grace
766 * period elapses, in other words after all currently executing RCU
767 * read-side critical sections have completed. call_rcu_bh() assumes
768 * that the read-side critical sections end on completion of a softirq
769 * handler. This means that read-side critical sections in process
770 * context must not be interrupted by softirqs. This interface is to be
771 * used when most of the read-side critical sections are in softirq context.
772 * RCU read-side critical sections are delimited by :
773 * - rcu_read_lock() and rcu_read_unlock(), if in interrupt context.
774 * OR
775 * - rcu_read_lock_bh() and rcu_read_unlock_bh(), if in process context.
776 * These may be nested.
777 */
778extern void call_rcu_bh(struct rcu_head *head,
779 void (*func)(struct rcu_head *head));
780
781/* 797/*
782 * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally 798 * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally
783 * by call_rcu() and rcu callback execution, and are therefore not part of the 799 * by call_rcu() and rcu callback execution, and are therefore not part of the
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
index 52b3e0281fd..4eab233a00c 100644
--- a/include/linux/rcutiny.h
+++ b/include/linux/rcutiny.h
@@ -31,6 +31,16 @@ static inline void rcu_init(void)
31{ 31{
32} 32}
33 33
34static inline void rcu_barrier_bh(void)
35{
36 wait_rcu_gp(call_rcu_bh);
37}
38
39static inline void rcu_barrier_sched(void)
40{
41 wait_rcu_gp(call_rcu_sched);
42}
43
34#ifdef CONFIG_TINY_RCU 44#ifdef CONFIG_TINY_RCU
35 45
36static inline void synchronize_rcu_expedited(void) 46static inline void synchronize_rcu_expedited(void)
@@ -45,9 +55,13 @@ static inline void rcu_barrier(void)
45 55
46#else /* #ifdef CONFIG_TINY_RCU */ 56#else /* #ifdef CONFIG_TINY_RCU */
47 57
48void rcu_barrier(void);
49void synchronize_rcu_expedited(void); 58void synchronize_rcu_expedited(void);
50 59
60static inline void rcu_barrier(void)
61{
62 wait_rcu_gp(call_rcu);
63}
64
51#endif /* #else #ifdef CONFIG_TINY_RCU */ 65#endif /* #else #ifdef CONFIG_TINY_RCU */
52 66
53static inline void synchronize_rcu_bh(void) 67static inline void synchronize_rcu_bh(void)
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index e65d06634dd..67458468f1a 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -67,6 +67,8 @@ static inline void synchronize_rcu_bh_expedited(void)
67} 67}
68 68
69extern void rcu_barrier(void); 69extern void rcu_barrier(void);
70extern void rcu_barrier_bh(void);
71extern void rcu_barrier_sched(void);
70 72
71extern unsigned long rcutorture_testseq; 73extern unsigned long rcutorture_testseq;
72extern unsigned long rcutorture_vernum; 74extern unsigned long rcutorture_vernum;