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 { |
