aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/srcu.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-04-29 19:53:17 -0400
committerH. Peter Anvin <hpa@zytor.com>2010-04-29 19:53:17 -0400
commitd9c5841e22231e4e49fd0a1004164e6fce59b7a6 (patch)
treee1f589c46b3ff79bbe7b1b2469f6362f94576da6 /kernel/srcu.c
parentb701a47ba48b698976fb2fe05fb285b0edc1d26a (diff)
parent5967ed87ade85a421ef814296c3c7f182b08c225 (diff)
Merge branch 'x86/asm' into x86/atomic
Merge reason: Conflict between LOCK_PREFIX_HERE and relative alternatives pointers Resolved Conflicts: arch/x86/include/asm/alternative.h arch/x86/kernel/alternative.c Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'kernel/srcu.c')
-rw-r--r--kernel/srcu.c53
1 files changed, 34 insertions, 19 deletions
diff --git a/kernel/srcu.c b/kernel/srcu.c
index 818d7d9aa03c..2980da3fd509 100644
--- a/kernel/srcu.c
+++ b/kernel/srcu.c
@@ -30,10 +30,33 @@
30#include <linux/preempt.h> 30#include <linux/preempt.h>
31#include <linux/rcupdate.h> 31#include <linux/rcupdate.h>
32#include <linux/sched.h> 32#include <linux/sched.h>
33#include <linux/slab.h>
34#include <linux/smp.h> 33#include <linux/smp.h>
35#include <linux/srcu.h> 34#include <linux/srcu.h>
36 35
36static int init_srcu_struct_fields(struct srcu_struct *sp)
37{
38 sp->completed = 0;
39 mutex_init(&sp->mutex);
40 sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array);
41 return sp->per_cpu_ref ? 0 : -ENOMEM;
42}
43
44#ifdef CONFIG_DEBUG_LOCK_ALLOC
45
46int __init_srcu_struct(struct srcu_struct *sp, const char *name,
47 struct lock_class_key *key)
48{
49#ifdef CONFIG_DEBUG_LOCK_ALLOC
50 /* Don't re-initialize a lock while it is held. */
51 debug_check_no_locks_freed((void *)sp, sizeof(*sp));
52 lockdep_init_map(&sp->dep_map, name, key, 0);
53#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
54 return init_srcu_struct_fields(sp);
55}
56EXPORT_SYMBOL_GPL(__init_srcu_struct);
57
58#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
59
37/** 60/**
38 * init_srcu_struct - initialize a sleep-RCU structure 61 * init_srcu_struct - initialize a sleep-RCU structure
39 * @sp: structure to initialize. 62 * @sp: structure to initialize.
@@ -44,13 +67,12 @@
44 */ 67 */
45int init_srcu_struct(struct srcu_struct *sp) 68int init_srcu_struct(struct srcu_struct *sp)
46{ 69{
47 sp->completed = 0; 70 return init_srcu_struct_fields(sp);
48 mutex_init(&sp->mutex);
49 sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array);
50 return (sp->per_cpu_ref ? 0 : -ENOMEM);
51} 71}
52EXPORT_SYMBOL_GPL(init_srcu_struct); 72EXPORT_SYMBOL_GPL(init_srcu_struct);
53 73
74#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
75
54/* 76/*
55 * srcu_readers_active_idx -- returns approximate number of readers 77 * srcu_readers_active_idx -- returns approximate number of readers
56 * active on the specified rank of per-CPU counters. 78 * active on the specified rank of per-CPU counters.
@@ -100,15 +122,12 @@ void cleanup_srcu_struct(struct srcu_struct *sp)
100} 122}
101EXPORT_SYMBOL_GPL(cleanup_srcu_struct); 123EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
102 124
103/** 125/*
104 * srcu_read_lock - register a new reader for an SRCU-protected structure.
105 * @sp: srcu_struct in which to register the new reader.
106 *
107 * Counts the new reader in the appropriate per-CPU element of the 126 * Counts the new reader in the appropriate per-CPU element of the
108 * srcu_struct. Must be called from process context. 127 * srcu_struct. Must be called from process context.
109 * Returns an index that must be passed to the matching srcu_read_unlock(). 128 * Returns an index that must be passed to the matching srcu_read_unlock().
110 */ 129 */
111int srcu_read_lock(struct srcu_struct *sp) 130int __srcu_read_lock(struct srcu_struct *sp)
112{ 131{
113 int idx; 132 int idx;
114 133
@@ -120,31 +139,27 @@ int srcu_read_lock(struct srcu_struct *sp)
120 preempt_enable(); 139 preempt_enable();
121 return idx; 140 return idx;
122} 141}
123EXPORT_SYMBOL_GPL(srcu_read_lock); 142EXPORT_SYMBOL_GPL(__srcu_read_lock);
124 143
125/** 144/*
126 * srcu_read_unlock - unregister a old reader from an SRCU-protected structure.
127 * @sp: srcu_struct in which to unregister the old reader.
128 * @idx: return value from corresponding srcu_read_lock().
129 *
130 * Removes the count for the old reader from the appropriate per-CPU 145 * Removes the count for the old reader from the appropriate per-CPU
131 * element of the srcu_struct. Note that this may well be a different 146 * element of the srcu_struct. Note that this may well be a different
132 * CPU than that which was incremented by the corresponding srcu_read_lock(). 147 * CPU than that which was incremented by the corresponding srcu_read_lock().
133 * Must be called from process context. 148 * Must be called from process context.
134 */ 149 */
135void srcu_read_unlock(struct srcu_struct *sp, int idx) 150void __srcu_read_unlock(struct srcu_struct *sp, int idx)
136{ 151{
137 preempt_disable(); 152 preempt_disable();
138 srcu_barrier(); /* ensure compiler won't misorder critical section. */ 153 srcu_barrier(); /* ensure compiler won't misorder critical section. */
139 per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]--; 154 per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]--;
140 preempt_enable(); 155 preempt_enable();
141} 156}
142EXPORT_SYMBOL_GPL(srcu_read_unlock); 157EXPORT_SYMBOL_GPL(__srcu_read_unlock);
143 158
144/* 159/*
145 * Helper function for synchronize_srcu() and synchronize_srcu_expedited(). 160 * Helper function for synchronize_srcu() and synchronize_srcu_expedited().
146 */ 161 */
147void __synchronize_srcu(struct srcu_struct *sp, void (*sync_func)(void)) 162static void __synchronize_srcu(struct srcu_struct *sp, void (*sync_func)(void))
148{ 163{
149 int idx; 164 int idx;
150 165