diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 12:23:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 12:23:07 -0400 |
commit | 3a3527b6461b1298cc53ce72f336346739297ac8 (patch) | |
tree | 30bea5dd7163f13d6c962888feaf53f50ead4cce | |
parent | cc77b4db0017dab014ad7ea3d297e10f5b5bf028 (diff) | |
parent | a53f4b61a76a7e95139b8e8abba02e9bfe87a58a (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:
Revert "net: Make accesses to ->br_port safe for sparse RCU"
mce: convert to rcu_dereference_index_check()
net: Make accesses to ->br_port safe for sparse RCU
vfs: add fs.h to define struct file
lockdep: Add an in_workqueue_context() lockdep-based test function
rcu: add __rcu API for later sparse checking
rcu: add an rcu_dereference_index_check()
tree/tiny rcu: Add debug RCU head objects
mm: remove all rcu head initializations
fs: remove all rcu head initializations, except on_stack initializations
powerpc: remove all rcu head initializations
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 2 | ||||
-rw-r--r-- | fs/file.c | 3 | ||||
-rw-r--r-- | fs/partitions/check.c | 1 | ||||
-rw-r--r-- | include/linux/compiler.h | 2 | ||||
-rw-r--r-- | include/linux/fdtable.h | 1 | ||||
-rw-r--r-- | include/linux/rcupdate.h | 82 | ||||
-rw-r--r-- | include/linux/workqueue.h | 4 | ||||
-rw-r--r-- | kernel/rcupdate.c | 160 | ||||
-rw-r--r-- | kernel/rcutiny.c | 2 | ||||
-rw-r--r-- | kernel/rcutree.c | 2 | ||||
-rw-r--r-- | kernel/workqueue.c | 15 | ||||
-rw-r--r-- | lib/Kconfig.debug | 6 | ||||
-rw-r--r-- | mm/backing-dev.c | 1 | ||||
-rw-r--r-- | mm/slob.c | 1 |
14 files changed, 275 insertions, 7 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 1970ef911c99..e1269d62c569 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -51,7 +51,7 @@ | |||
51 | static DEFINE_MUTEX(mce_read_mutex); | 51 | static DEFINE_MUTEX(mce_read_mutex); |
52 | 52 | ||
53 | #define rcu_dereference_check_mce(p) \ | 53 | #define rcu_dereference_check_mce(p) \ |
54 | rcu_dereference_check((p), \ | 54 | rcu_dereference_index_check((p), \ |
55 | rcu_read_lock_sched_held() || \ | 55 | rcu_read_lock_sched_held() || \ |
56 | lockdep_is_held(&mce_read_mutex)) | 56 | lockdep_is_held(&mce_read_mutex)) |
57 | 57 | ||
@@ -178,7 +178,6 @@ static struct fdtable * alloc_fdtable(unsigned int nr) | |||
178 | fdt->open_fds = (fd_set *)data; | 178 | fdt->open_fds = (fd_set *)data; |
179 | data += nr / BITS_PER_BYTE; | 179 | data += nr / BITS_PER_BYTE; |
180 | fdt->close_on_exec = (fd_set *)data; | 180 | fdt->close_on_exec = (fd_set *)data; |
181 | INIT_RCU_HEAD(&fdt->rcu); | ||
182 | fdt->next = NULL; | 181 | fdt->next = NULL; |
183 | 182 | ||
184 | return fdt; | 183 | return fdt; |
@@ -312,7 +311,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
312 | new_fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init; | 311 | new_fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init; |
313 | new_fdt->open_fds = (fd_set *)&newf->open_fds_init; | 312 | new_fdt->open_fds = (fd_set *)&newf->open_fds_init; |
314 | new_fdt->fd = &newf->fd_array[0]; | 313 | new_fdt->fd = &newf->fd_array[0]; |
315 | INIT_RCU_HEAD(&new_fdt->rcu); | ||
316 | new_fdt->next = NULL; | 314 | new_fdt->next = NULL; |
317 | 315 | ||
318 | spin_lock(&oldf->file_lock); | 316 | spin_lock(&oldf->file_lock); |
@@ -430,7 +428,6 @@ struct files_struct init_files = { | |||
430 | .fd = &init_files.fd_array[0], | 428 | .fd = &init_files.fd_array[0], |
431 | .close_on_exec = (fd_set *)&init_files.close_on_exec_init, | 429 | .close_on_exec = (fd_set *)&init_files.close_on_exec_init, |
432 | .open_fds = (fd_set *)&init_files.open_fds_init, | 430 | .open_fds = (fd_set *)&init_files.open_fds_init, |
433 | .rcu = RCU_HEAD_INIT, | ||
434 | }, | 431 | }, |
435 | .file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock), | 432 | .file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock), |
436 | }; | 433 | }; |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 5dcd4b0c5533..72c52656dc2e 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -459,7 +459,6 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
459 | } | 459 | } |
460 | 460 | ||
461 | /* everything is up and running, commence */ | 461 | /* everything is up and running, commence */ |
462 | INIT_RCU_HEAD(&p->rcu_head); | ||
463 | rcu_assign_pointer(ptbl->part[partno], p); | 462 | rcu_assign_pointer(ptbl->part[partno], p); |
464 | 463 | ||
465 | /* suppress uevent if the disk supresses it */ | 464 | /* suppress uevent if the disk supresses it */ |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index a5a472b10746..c1a62c56a660 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -16,6 +16,7 @@ | |||
16 | # define __release(x) __context__(x,-1) | 16 | # define __release(x) __context__(x,-1) |
17 | # define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) | 17 | # define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) |
18 | # define __percpu __attribute__((noderef, address_space(3))) | 18 | # define __percpu __attribute__((noderef, address_space(3))) |
19 | # define __rcu | ||
19 | extern void __chk_user_ptr(const volatile void __user *); | 20 | extern void __chk_user_ptr(const volatile void __user *); |
20 | extern void __chk_io_ptr(const volatile void __iomem *); | 21 | extern void __chk_io_ptr(const volatile void __iomem *); |
21 | #else | 22 | #else |
@@ -34,6 +35,7 @@ extern void __chk_io_ptr(const volatile void __iomem *); | |||
34 | # define __release(x) (void)0 | 35 | # define __release(x) (void)0 |
35 | # define __cond_lock(x,c) (c) | 36 | # define __cond_lock(x,c) (c) |
36 | # define __percpu | 37 | # define __percpu |
38 | # define __rcu | ||
37 | #endif | 39 | #endif |
38 | 40 | ||
39 | #ifdef __KERNEL__ | 41 | #ifdef __KERNEL__ |
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index d147461bc271..f59ed297b661 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/rcupdate.h> | 11 | #include <linux/rcupdate.h> |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/fs.h> | ||
14 | 15 | ||
15 | #include <asm/atomic.h> | 16 | #include <asm/atomic.h> |
16 | 17 | ||
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index b653b4aaa8a6..9fbc54a2585d 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/seqlock.h> | 40 | #include <linux/seqlock.h> |
41 | #include <linux/lockdep.h> | 41 | #include <linux/lockdep.h> |
42 | #include <linux/completion.h> | 42 | #include <linux/completion.h> |
43 | #include <linux/debugobjects.h> | ||
43 | 44 | ||
44 | #ifdef CONFIG_RCU_TORTURE_TEST | 45 | #ifdef CONFIG_RCU_TORTURE_TEST |
45 | extern int rcutorture_runnable; /* for sysctl */ | 46 | extern int rcutorture_runnable; /* for sysctl */ |
@@ -79,6 +80,16 @@ extern void rcu_init(void); | |||
79 | (ptr)->next = NULL; (ptr)->func = NULL; \ | 80 | (ptr)->next = NULL; (ptr)->func = NULL; \ |
80 | } while (0) | 81 | } while (0) |
81 | 82 | ||
83 | /* | ||
84 | * init_rcu_head_on_stack()/destroy_rcu_head_on_stack() are needed for dynamic | ||
85 | * initialization and destruction of rcu_head on the stack. rcu_head structures | ||
86 | * allocated dynamically in the heap or defined statically don't need any | ||
87 | * initialization. | ||
88 | */ | ||
89 | #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD | ||
90 | extern void init_rcu_head_on_stack(struct rcu_head *head); | ||
91 | extern void destroy_rcu_head_on_stack(struct rcu_head *head); | ||
92 | #else /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ | ||
82 | static inline void init_rcu_head_on_stack(struct rcu_head *head) | 93 | static inline void init_rcu_head_on_stack(struct rcu_head *head) |
83 | { | 94 | { |
84 | } | 95 | } |
@@ -86,6 +97,7 @@ static inline void init_rcu_head_on_stack(struct rcu_head *head) | |||
86 | static inline void destroy_rcu_head_on_stack(struct rcu_head *head) | 97 | static inline void destroy_rcu_head_on_stack(struct rcu_head *head) |
87 | { | 98 | { |
88 | } | 99 | } |
100 | #endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ | ||
89 | 101 | ||
90 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 102 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
91 | 103 | ||
@@ -517,4 +529,74 @@ extern void call_rcu(struct rcu_head *head, | |||
517 | extern void call_rcu_bh(struct rcu_head *head, | 529 | extern void call_rcu_bh(struct rcu_head *head, |
518 | void (*func)(struct rcu_head *head)); | 530 | void (*func)(struct rcu_head *head)); |
519 | 531 | ||
532 | /* | ||
533 | * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally | ||
534 | * by call_rcu() and rcu callback execution, and are therefore not part of the | ||
535 | * RCU API. Leaving in rcupdate.h because they are used by all RCU flavors. | ||
536 | */ | ||
537 | |||
538 | #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD | ||
539 | # define STATE_RCU_HEAD_READY 0 | ||
540 | # define STATE_RCU_HEAD_QUEUED 1 | ||
541 | |||
542 | extern struct debug_obj_descr rcuhead_debug_descr; | ||
543 | |||
544 | static inline void debug_rcu_head_queue(struct rcu_head *head) | ||
545 | { | ||
546 | debug_object_activate(head, &rcuhead_debug_descr); | ||
547 | debug_object_active_state(head, &rcuhead_debug_descr, | ||
548 | STATE_RCU_HEAD_READY, | ||
549 | STATE_RCU_HEAD_QUEUED); | ||
550 | } | ||
551 | |||
552 | static inline void debug_rcu_head_unqueue(struct rcu_head *head) | ||
553 | { | ||
554 | debug_object_active_state(head, &rcuhead_debug_descr, | ||
555 | STATE_RCU_HEAD_QUEUED, | ||
556 | STATE_RCU_HEAD_READY); | ||
557 | debug_object_deactivate(head, &rcuhead_debug_descr); | ||
558 | } | ||
559 | #else /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ | ||
560 | static inline void debug_rcu_head_queue(struct rcu_head *head) | ||
561 | { | ||
562 | } | ||
563 | |||
564 | static inline void debug_rcu_head_unqueue(struct rcu_head *head) | ||
565 | { | ||
566 | } | ||
567 | #endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ | ||
568 | |||
569 | #ifndef CONFIG_PROVE_RCU | ||
570 | #define __do_rcu_dereference_check(c) do { } while (0) | ||
571 | #endif /* #ifdef CONFIG_PROVE_RCU */ | ||
572 | |||
573 | #define __rcu_dereference_index_check(p, c) \ | ||
574 | ({ \ | ||
575 | typeof(p) _________p1 = ACCESS_ONCE(p); \ | ||
576 | __do_rcu_dereference_check(c); \ | ||
577 | smp_read_barrier_depends(); \ | ||
578 | (_________p1); \ | ||
579 | }) | ||
580 | |||
581 | /** | ||
582 | * rcu_dereference_index_check() - rcu_dereference for indices with debug checking | ||
583 | * @p: The pointer to read, prior to dereferencing | ||
584 | * @c: The conditions under which the dereference will take place | ||
585 | * | ||
586 | * Similar to rcu_dereference_check(), but omits the sparse checking. | ||
587 | * This allows rcu_dereference_index_check() to be used on integers, | ||
588 | * which can then be used as array indices. Attempting to use | ||
589 | * rcu_dereference_check() on an integer will give compiler warnings | ||
590 | * because the sparse address-space mechanism relies on dereferencing | ||
591 | * the RCU-protected pointer. Dereferencing integers is not something | ||
592 | * that even gcc will put up with. | ||
593 | * | ||
594 | * Note that this function does not implicitly check for RCU read-side | ||
595 | * critical sections. If this function gains lots of uses, it might | ||
596 | * make sense to provide versions for each flavor of RCU, but it does | ||
597 | * not make sense as of early 2010. | ||
598 | */ | ||
599 | #define rcu_dereference_index_check(p, c) \ | ||
600 | __rcu_dereference_index_check((p), (c)) | ||
601 | |||
520 | #endif /* __LINUX_RCUPDATE_H */ | 602 | #endif /* __LINUX_RCUPDATE_H */ |
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 9466e860d8c2..d0f7c8178498 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
@@ -297,4 +297,8 @@ static inline long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) | |||
297 | #else | 297 | #else |
298 | long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg); | 298 | long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg); |
299 | #endif /* CONFIG_SMP */ | 299 | #endif /* CONFIG_SMP */ |
300 | |||
301 | #ifdef CONFIG_LOCKDEP | ||
302 | int in_workqueue_context(struct workqueue_struct *wq); | ||
303 | #endif | ||
300 | #endif | 304 | #endif |
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 72a8dc9567f5..4d169835fb36 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
@@ -114,3 +114,163 @@ int rcu_my_thread_group_empty(void) | |||
114 | } | 114 | } |
115 | EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty); | 115 | EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty); |
116 | #endif /* #ifdef CONFIG_PROVE_RCU */ | 116 | #endif /* #ifdef CONFIG_PROVE_RCU */ |
117 | |||
118 | #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD | ||
119 | static inline void debug_init_rcu_head(struct rcu_head *head) | ||
120 | { | ||
121 | debug_object_init(head, &rcuhead_debug_descr); | ||
122 | } | ||
123 | |||
124 | static inline void debug_rcu_head_free(struct rcu_head *head) | ||
125 | { | ||
126 | debug_object_free(head, &rcuhead_debug_descr); | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * fixup_init is called when: | ||
131 | * - an active object is initialized | ||
132 | */ | ||
133 | static int rcuhead_fixup_init(void *addr, enum debug_obj_state state) | ||
134 | { | ||
135 | struct rcu_head *head = addr; | ||
136 | |||
137 | switch (state) { | ||
138 | case ODEBUG_STATE_ACTIVE: | ||
139 | /* | ||
140 | * Ensure that queued callbacks are all executed. | ||
141 | * If we detect that we are nested in a RCU read-side critical | ||
142 | * section, we should simply fail, otherwise we would deadlock. | ||
143 | */ | ||
144 | if (rcu_preempt_depth() != 0 || preempt_count() != 0 || | ||
145 | irqs_disabled()) { | ||
146 | WARN_ON(1); | ||
147 | return 0; | ||
148 | } | ||
149 | rcu_barrier(); | ||
150 | rcu_barrier_sched(); | ||
151 | rcu_barrier_bh(); | ||
152 | debug_object_init(head, &rcuhead_debug_descr); | ||
153 | return 1; | ||
154 | default: | ||
155 | return 0; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * fixup_activate is called when: | ||
161 | * - an active object is activated | ||
162 | * - an unknown object is activated (might be a statically initialized object) | ||
163 | * Activation is performed internally by call_rcu(). | ||
164 | */ | ||
165 | static int rcuhead_fixup_activate(void *addr, enum debug_obj_state state) | ||
166 | { | ||
167 | struct rcu_head *head = addr; | ||
168 | |||
169 | switch (state) { | ||
170 | |||
171 | case ODEBUG_STATE_NOTAVAILABLE: | ||
172 | /* | ||
173 | * This is not really a fixup. We just make sure that it is | ||
174 | * tracked in the object tracker. | ||
175 | */ | ||
176 | debug_object_init(head, &rcuhead_debug_descr); | ||
177 | debug_object_activate(head, &rcuhead_debug_descr); | ||
178 | return 0; | ||
179 | |||
180 | case ODEBUG_STATE_ACTIVE: | ||
181 | /* | ||
182 | * Ensure that queued callbacks are all executed. | ||
183 | * If we detect that we are nested in a RCU read-side critical | ||
184 | * section, we should simply fail, otherwise we would deadlock. | ||
185 | */ | ||
186 | if (rcu_preempt_depth() != 0 || preempt_count() != 0 || | ||
187 | irqs_disabled()) { | ||
188 | WARN_ON(1); | ||
189 | return 0; | ||
190 | } | ||
191 | rcu_barrier(); | ||
192 | rcu_barrier_sched(); | ||
193 | rcu_barrier_bh(); | ||
194 | debug_object_activate(head, &rcuhead_debug_descr); | ||
195 | return 1; | ||
196 | default: | ||
197 | return 0; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * fixup_free is called when: | ||
203 | * - an active object is freed | ||
204 | */ | ||
205 | static int rcuhead_fixup_free(void *addr, enum debug_obj_state state) | ||
206 | { | ||
207 | struct rcu_head *head = addr; | ||
208 | |||
209 | switch (state) { | ||
210 | case ODEBUG_STATE_ACTIVE: | ||
211 | /* | ||
212 | * Ensure that queued callbacks are all executed. | ||
213 | * If we detect that we are nested in a RCU read-side critical | ||
214 | * section, we should simply fail, otherwise we would deadlock. | ||
215 | */ | ||
216 | #ifndef CONFIG_PREEMPT | ||
217 | WARN_ON(1); | ||
218 | return 0; | ||
219 | #else | ||
220 | if (rcu_preempt_depth() != 0 || preempt_count() != 0 || | ||
221 | irqs_disabled()) { | ||
222 | WARN_ON(1); | ||
223 | return 0; | ||
224 | } | ||
225 | rcu_barrier(); | ||
226 | rcu_barrier_sched(); | ||
227 | rcu_barrier_bh(); | ||
228 | debug_object_free(head, &rcuhead_debug_descr); | ||
229 | return 1; | ||
230 | #endif | ||
231 | default: | ||
232 | return 0; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | /** | ||
237 | * init_rcu_head_on_stack() - initialize on-stack rcu_head for debugobjects | ||
238 | * @head: pointer to rcu_head structure to be initialized | ||
239 | * | ||
240 | * This function informs debugobjects of a new rcu_head structure that | ||
241 | * has been allocated as an auto variable on the stack. This function | ||
242 | * is not required for rcu_head structures that are statically defined or | ||
243 | * that are dynamically allocated on the heap. This function has no | ||
244 | * effect for !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds. | ||
245 | */ | ||
246 | void init_rcu_head_on_stack(struct rcu_head *head) | ||
247 | { | ||
248 | debug_object_init_on_stack(head, &rcuhead_debug_descr); | ||
249 | } | ||
250 | EXPORT_SYMBOL_GPL(init_rcu_head_on_stack); | ||
251 | |||
252 | /** | ||
253 | * destroy_rcu_head_on_stack() - destroy on-stack rcu_head for debugobjects | ||
254 | * @head: pointer to rcu_head structure to be initialized | ||
255 | * | ||
256 | * This function informs debugobjects that an on-stack rcu_head structure | ||
257 | * is about to go out of scope. As with init_rcu_head_on_stack(), this | ||
258 | * function is not required for rcu_head structures that are statically | ||
259 | * defined or that are dynamically allocated on the heap. Also as with | ||
260 | * init_rcu_head_on_stack(), this function has no effect for | ||
261 | * !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds. | ||
262 | */ | ||
263 | void destroy_rcu_head_on_stack(struct rcu_head *head) | ||
264 | { | ||
265 | debug_object_free(head, &rcuhead_debug_descr); | ||
266 | } | ||
267 | EXPORT_SYMBOL_GPL(destroy_rcu_head_on_stack); | ||
268 | |||
269 | struct debug_obj_descr rcuhead_debug_descr = { | ||
270 | .name = "rcu_head", | ||
271 | .fixup_init = rcuhead_fixup_init, | ||
272 | .fixup_activate = rcuhead_fixup_activate, | ||
273 | .fixup_free = rcuhead_fixup_free, | ||
274 | }; | ||
275 | EXPORT_SYMBOL_GPL(rcuhead_debug_descr); | ||
276 | #endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */ | ||
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c index 38729d3cd236..196ec02f8be0 100644 --- a/kernel/rcutiny.c +++ b/kernel/rcutiny.c | |||
@@ -169,6 +169,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp) | |||
169 | while (list) { | 169 | while (list) { |
170 | next = list->next; | 170 | next = list->next; |
171 | prefetch(next); | 171 | prefetch(next); |
172 | debug_rcu_head_unqueue(list); | ||
172 | list->func(list); | 173 | list->func(list); |
173 | list = next; | 174 | list = next; |
174 | } | 175 | } |
@@ -211,6 +212,7 @@ static void __call_rcu(struct rcu_head *head, | |||
211 | { | 212 | { |
212 | unsigned long flags; | 213 | unsigned long flags; |
213 | 214 | ||
215 | debug_rcu_head_queue(head); | ||
214 | head->func = func; | 216 | head->func = func; |
215 | head->next = NULL; | 217 | head->next = NULL; |
216 | 218 | ||
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index d4437345706f..d5bc43976c5a 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -1112,6 +1112,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1112 | while (list) { | 1112 | while (list) { |
1113 | next = list->next; | 1113 | next = list->next; |
1114 | prefetch(next); | 1114 | prefetch(next); |
1115 | debug_rcu_head_unqueue(list); | ||
1115 | list->func(list); | 1116 | list->func(list); |
1116 | list = next; | 1117 | list = next; |
1117 | if (++count >= rdp->blimit) | 1118 | if (++count >= rdp->blimit) |
@@ -1388,6 +1389,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), | |||
1388 | unsigned long flags; | 1389 | unsigned long flags; |
1389 | struct rcu_data *rdp; | 1390 | struct rcu_data *rdp; |
1390 | 1391 | ||
1392 | debug_rcu_head_queue(head); | ||
1391 | head->func = func; | 1393 | head->func = func; |
1392 | head->next = NULL; | 1394 | head->next = NULL; |
1393 | 1395 | ||
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 327d2deb4451..59fef1531dd2 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -68,6 +68,21 @@ struct workqueue_struct { | |||
68 | #endif | 68 | #endif |
69 | }; | 69 | }; |
70 | 70 | ||
71 | #ifdef CONFIG_LOCKDEP | ||
72 | /** | ||
73 | * in_workqueue_context() - in context of specified workqueue? | ||
74 | * @wq: the workqueue of interest | ||
75 | * | ||
76 | * Checks lockdep state to see if the current task is executing from | ||
77 | * within a workqueue item. This function exists only if lockdep is | ||
78 | * enabled. | ||
79 | */ | ||
80 | int in_workqueue_context(struct workqueue_struct *wq) | ||
81 | { | ||
82 | return lock_is_held(&wq->lockdep_map); | ||
83 | } | ||
84 | #endif | ||
85 | |||
71 | #ifdef CONFIG_DEBUG_OBJECTS_WORK | 86 | #ifdef CONFIG_DEBUG_OBJECTS_WORK |
72 | 87 | ||
73 | static struct debug_obj_descr work_debug_descr; | 88 | static struct debug_obj_descr work_debug_descr; |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 67fa774f9572..e80d6bf1c43d 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -307,6 +307,12 @@ config DEBUG_OBJECTS_WORK | |||
307 | work queue routines to track the life time of work objects and | 307 | work queue routines to track the life time of work objects and |
308 | validate the work operations. | 308 | validate the work operations. |
309 | 309 | ||
310 | config DEBUG_OBJECTS_RCU_HEAD | ||
311 | bool "Debug RCU callbacks objects" | ||
312 | depends on DEBUG_OBJECTS && PREEMPT | ||
313 | help | ||
314 | Enable this to turn on debugging of RCU list heads (call_rcu() usage). | ||
315 | |||
310 | config DEBUG_OBJECTS_ENABLE_DEFAULT | 316 | config DEBUG_OBJECTS_ENABLE_DEFAULT |
311 | int "debug_objects bootup default value (0-1)" | 317 | int "debug_objects bootup default value (0-1)" |
312 | range 0 1 | 318 | range 0 1 |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 123bcef13e51..f9fd3dd3916b 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -665,7 +665,6 @@ int bdi_init(struct backing_dev_info *bdi) | |||
665 | bdi->max_ratio = 100; | 665 | bdi->max_ratio = 100; |
666 | bdi->max_prop_frac = PROP_FRAC_BASE; | 666 | bdi->max_prop_frac = PROP_FRAC_BASE; |
667 | spin_lock_init(&bdi->wb_lock); | 667 | spin_lock_init(&bdi->wb_lock); |
668 | INIT_RCU_HEAD(&bdi->rcu_head); | ||
669 | INIT_LIST_HEAD(&bdi->bdi_list); | 668 | INIT_LIST_HEAD(&bdi->bdi_list); |
670 | INIT_LIST_HEAD(&bdi->wb_list); | 669 | INIT_LIST_HEAD(&bdi->wb_list); |
671 | INIT_LIST_HEAD(&bdi->work_list); | 670 | INIT_LIST_HEAD(&bdi->work_list); |
@@ -639,7 +639,6 @@ void kmem_cache_free(struct kmem_cache *c, void *b) | |||
639 | if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) { | 639 | if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) { |
640 | struct slob_rcu *slob_rcu; | 640 | struct slob_rcu *slob_rcu; |
641 | slob_rcu = b + (c->size - sizeof(struct slob_rcu)); | 641 | slob_rcu = b + (c->size - sizeof(struct slob_rcu)); |
642 | INIT_RCU_HEAD(&slob_rcu->head); | ||
643 | slob_rcu->size = c->size; | 642 | slob_rcu->size = c->size; |
644 | call_rcu(&slob_rcu->head, kmem_rcu_free); | 643 | call_rcu(&slob_rcu->head, kmem_rcu_free); |
645 | } else { | 644 | } else { |