diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-28 13:13:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-28 13:13:16 -0500 |
commit | 642c4c75a765d7a3244ab39c8e6fb09be21eca5b (patch) | |
tree | ce0be9b476f362835d3a3d6e4fd32801cd15c9fe /kernel/srcu.c | |
parent | f91b22c35f6b0ae06ec5b67922eca1999c3b6e0a (diff) | |
parent | 71da81324c83ef65bb196c7f874ac1c6996d8287 (diff) |
Merge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (44 commits)
rcu: Fix accelerated GPs for last non-dynticked CPU
rcu: Make non-RCU_PROVE_LOCKING rcu_read_lock_sched_held() understand boot
rcu: Fix accelerated grace periods for last non-dynticked CPU
rcu: Export rcu_scheduler_active
rcu: Make rcu_read_lock_sched_held() take boot time into account
rcu: Make lockdep_rcu_dereference() message less alarmist
sched, cgroups: Fix module export
rcu: Add RCU_CPU_STALL_VERBOSE to dump detailed per-task information
rcu: Fix rcutorture mod_timer argument to delay one jiffy
rcu: Fix deadlock in TREE_PREEMPT_RCU CPU stall detection
rcu: Convert to raw_spinlocks
rcu: Stop overflowing signed integers
rcu: Use canonical URL for Mathieu's dissertation
rcu: Accelerate grace period if last non-dynticked CPU
rcu: Fix citation of Mathieu's dissertation
rcu: Documentation update for CONFIG_PROVE_RCU
security: Apply lockdep-based checking to rcu_dereference() uses
idr: Apply lockdep-based diagnostics to rcu_dereference() uses
radix-tree: Disable RCU lockdep checking in radix tree
vfs: Abstract rcu_dereference_check for files-fdtable use
...
Diffstat (limited to 'kernel/srcu.c')
-rw-r--r-- | kernel/srcu.c | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/kernel/srcu.c b/kernel/srcu.c index 818d7d9aa03c..bde4295774c8 100644 --- a/kernel/srcu.c +++ b/kernel/srcu.c | |||
@@ -34,6 +34,30 @@ | |||
34 | #include <linux/smp.h> | 34 | #include <linux/smp.h> |
35 | #include <linux/srcu.h> | 35 | #include <linux/srcu.h> |
36 | 36 | ||
37 | static int init_srcu_struct_fields(struct srcu_struct *sp) | ||
38 | { | ||
39 | sp->completed = 0; | ||
40 | mutex_init(&sp->mutex); | ||
41 | sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array); | ||
42 | return sp->per_cpu_ref ? 0 : -ENOMEM; | ||
43 | } | ||
44 | |||
45 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
46 | |||
47 | int __init_srcu_struct(struct srcu_struct *sp, const char *name, | ||
48 | struct lock_class_key *key) | ||
49 | { | ||
50 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
51 | /* Don't re-initialize a lock while it is held. */ | ||
52 | debug_check_no_locks_freed((void *)sp, sizeof(*sp)); | ||
53 | lockdep_init_map(&sp->dep_map, name, key, 0); | ||
54 | #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ | ||
55 | return init_srcu_struct_fields(sp); | ||
56 | } | ||
57 | EXPORT_SYMBOL_GPL(__init_srcu_struct); | ||
58 | |||
59 | #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ | ||
60 | |||
37 | /** | 61 | /** |
38 | * init_srcu_struct - initialize a sleep-RCU structure | 62 | * init_srcu_struct - initialize a sleep-RCU structure |
39 | * @sp: structure to initialize. | 63 | * @sp: structure to initialize. |
@@ -44,13 +68,12 @@ | |||
44 | */ | 68 | */ |
45 | int init_srcu_struct(struct srcu_struct *sp) | 69 | int init_srcu_struct(struct srcu_struct *sp) |
46 | { | 70 | { |
47 | sp->completed = 0; | 71 | 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 | } | 72 | } |
52 | EXPORT_SYMBOL_GPL(init_srcu_struct); | 73 | EXPORT_SYMBOL_GPL(init_srcu_struct); |
53 | 74 | ||
75 | #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ | ||
76 | |||
54 | /* | 77 | /* |
55 | * srcu_readers_active_idx -- returns approximate number of readers | 78 | * srcu_readers_active_idx -- returns approximate number of readers |
56 | * active on the specified rank of per-CPU counters. | 79 | * active on the specified rank of per-CPU counters. |
@@ -100,15 +123,12 @@ void cleanup_srcu_struct(struct srcu_struct *sp) | |||
100 | } | 123 | } |
101 | EXPORT_SYMBOL_GPL(cleanup_srcu_struct); | 124 | EXPORT_SYMBOL_GPL(cleanup_srcu_struct); |
102 | 125 | ||
103 | /** | 126 | /* |
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 | 127 | * Counts the new reader in the appropriate per-CPU element of the |
108 | * srcu_struct. Must be called from process context. | 128 | * srcu_struct. Must be called from process context. |
109 | * Returns an index that must be passed to the matching srcu_read_unlock(). | 129 | * Returns an index that must be passed to the matching srcu_read_unlock(). |
110 | */ | 130 | */ |
111 | int srcu_read_lock(struct srcu_struct *sp) | 131 | int __srcu_read_lock(struct srcu_struct *sp) |
112 | { | 132 | { |
113 | int idx; | 133 | int idx; |
114 | 134 | ||
@@ -120,31 +140,27 @@ int srcu_read_lock(struct srcu_struct *sp) | |||
120 | preempt_enable(); | 140 | preempt_enable(); |
121 | return idx; | 141 | return idx; |
122 | } | 142 | } |
123 | EXPORT_SYMBOL_GPL(srcu_read_lock); | 143 | EXPORT_SYMBOL_GPL(__srcu_read_lock); |
124 | 144 | ||
125 | /** | 145 | /* |
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 | 146 | * 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 | 147 | * 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(). | 148 | * CPU than that which was incremented by the corresponding srcu_read_lock(). |
133 | * Must be called from process context. | 149 | * Must be called from process context. |
134 | */ | 150 | */ |
135 | void srcu_read_unlock(struct srcu_struct *sp, int idx) | 151 | void __srcu_read_unlock(struct srcu_struct *sp, int idx) |
136 | { | 152 | { |
137 | preempt_disable(); | 153 | preempt_disable(); |
138 | srcu_barrier(); /* ensure compiler won't misorder critical section. */ | 154 | srcu_barrier(); /* ensure compiler won't misorder critical section. */ |
139 | per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]--; | 155 | per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]--; |
140 | preempt_enable(); | 156 | preempt_enable(); |
141 | } | 157 | } |
142 | EXPORT_SYMBOL_GPL(srcu_read_unlock); | 158 | EXPORT_SYMBOL_GPL(__srcu_read_unlock); |
143 | 159 | ||
144 | /* | 160 | /* |
145 | * Helper function for synchronize_srcu() and synchronize_srcu_expedited(). | 161 | * Helper function for synchronize_srcu() and synchronize_srcu_expedited(). |
146 | */ | 162 | */ |
147 | void __synchronize_srcu(struct srcu_struct *sp, void (*sync_func)(void)) | 163 | static void __synchronize_srcu(struct srcu_struct *sp, void (*sync_func)(void)) |
148 | { | 164 | { |
149 | int idx; | 165 | int idx; |
150 | 166 | ||