diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/compiler.h | 2 | ||||
| -rw-r--r-- | include/linux/rculist.h | 16 | ||||
| -rw-r--r-- | include/linux/rcupdate.h | 13 | ||||
| -rw-r--r-- | include/linux/rcutiny.h | 45 | ||||
| -rw-r--r-- | include/linux/rcutree.h | 11 | ||||
| -rw-r--r-- | include/linux/srcu.h | 14 |
6 files changed, 70 insertions, 31 deletions
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index a1c81f80978e..49811cdddaa5 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
| @@ -385,7 +385,7 @@ static __always_inline void __assign_once_size(volatile void *p, void *res, int | |||
| 385 | 385 | ||
| 386 | /* Is this type a native word size -- useful for atomic operations */ | 386 | /* Is this type a native word size -- useful for atomic operations */ |
| 387 | #ifndef __native_word | 387 | #ifndef __native_word |
| 388 | # define __native_word(t) (sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) | 388 | # define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) |
| 389 | #endif | 389 | #endif |
| 390 | 390 | ||
| 391 | /* Compile time object size, -1 for unknown */ | 391 | /* Compile time object size, -1 for unknown */ |
diff --git a/include/linux/rculist.h b/include/linux/rculist.h index 529bc946f450..a18b16f1dc0e 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h | |||
| @@ -524,11 +524,11 @@ static inline void hlist_add_behind_rcu(struct hlist_node *n, | |||
| 524 | * @member: the name of the hlist_node within the struct. | 524 | * @member: the name of the hlist_node within the struct. |
| 525 | */ | 525 | */ |
| 526 | #define hlist_for_each_entry_continue_rcu(pos, member) \ | 526 | #define hlist_for_each_entry_continue_rcu(pos, member) \ |
| 527 | for (pos = hlist_entry_safe(rcu_dereference((pos)->member.next),\ | 527 | for (pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \ |
| 528 | typeof(*(pos)), member); \ | 528 | &(pos)->member)), typeof(*(pos)), member); \ |
| 529 | pos; \ | 529 | pos; \ |
| 530 | pos = hlist_entry_safe(rcu_dereference((pos)->member.next),\ | 530 | pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \ |
| 531 | typeof(*(pos)), member)) | 531 | &(pos)->member)), typeof(*(pos)), member)) |
| 532 | 532 | ||
| 533 | /** | 533 | /** |
| 534 | * hlist_for_each_entry_continue_rcu_bh - iterate over a hlist continuing after current point | 534 | * hlist_for_each_entry_continue_rcu_bh - iterate over a hlist continuing after current point |
| @@ -536,11 +536,11 @@ static inline void hlist_add_behind_rcu(struct hlist_node *n, | |||
| 536 | * @member: the name of the hlist_node within the struct. | 536 | * @member: the name of the hlist_node within the struct. |
| 537 | */ | 537 | */ |
| 538 | #define hlist_for_each_entry_continue_rcu_bh(pos, member) \ | 538 | #define hlist_for_each_entry_continue_rcu_bh(pos, member) \ |
| 539 | for (pos = hlist_entry_safe(rcu_dereference_bh((pos)->member.next),\ | 539 | for (pos = hlist_entry_safe(rcu_dereference_bh(hlist_next_rcu( \ |
| 540 | typeof(*(pos)), member); \ | 540 | &(pos)->member)), typeof(*(pos)), member); \ |
| 541 | pos; \ | 541 | pos; \ |
| 542 | pos = hlist_entry_safe(rcu_dereference_bh((pos)->member.next),\ | 542 | pos = hlist_entry_safe(rcu_dereference_bh(hlist_next_rcu( \ |
| 543 | typeof(*(pos)), member)) | 543 | &(pos)->member)), typeof(*(pos)), member)) |
| 544 | 544 | ||
| 545 | /** | 545 | /** |
| 546 | * hlist_for_each_entry_from_rcu - iterate over a hlist continuing from current point | 546 | * hlist_for_each_entry_from_rcu - iterate over a hlist continuing from current point |
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index ed4f5939a452..78097491cd99 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
| @@ -331,12 +331,13 @@ static inline void rcu_init_nohz(void) | |||
| 331 | extern struct srcu_struct tasks_rcu_exit_srcu; | 331 | extern struct srcu_struct tasks_rcu_exit_srcu; |
| 332 | #define rcu_note_voluntary_context_switch(t) \ | 332 | #define rcu_note_voluntary_context_switch(t) \ |
| 333 | do { \ | 333 | do { \ |
| 334 | rcu_all_qs(); \ | ||
| 334 | if (ACCESS_ONCE((t)->rcu_tasks_holdout)) \ | 335 | if (ACCESS_ONCE((t)->rcu_tasks_holdout)) \ |
| 335 | ACCESS_ONCE((t)->rcu_tasks_holdout) = false; \ | 336 | ACCESS_ONCE((t)->rcu_tasks_holdout) = false; \ |
| 336 | } while (0) | 337 | } while (0) |
| 337 | #else /* #ifdef CONFIG_TASKS_RCU */ | 338 | #else /* #ifdef CONFIG_TASKS_RCU */ |
| 338 | #define TASKS_RCU(x) do { } while (0) | 339 | #define TASKS_RCU(x) do { } while (0) |
| 339 | #define rcu_note_voluntary_context_switch(t) do { } while (0) | 340 | #define rcu_note_voluntary_context_switch(t) rcu_all_qs() |
| 340 | #endif /* #else #ifdef CONFIG_TASKS_RCU */ | 341 | #endif /* #else #ifdef CONFIG_TASKS_RCU */ |
| 341 | 342 | ||
| 342 | /** | 343 | /** |
| @@ -582,11 +583,11 @@ static inline void rcu_preempt_sleep_check(void) | |||
| 582 | }) | 583 | }) |
| 583 | #define __rcu_dereference_check(p, c, space) \ | 584 | #define __rcu_dereference_check(p, c, space) \ |
| 584 | ({ \ | 585 | ({ \ |
| 585 | typeof(*p) *_________p1 = (typeof(*p) *__force)ACCESS_ONCE(p); \ | 586 | /* Dependency order vs. p above. */ \ |
| 587 | typeof(*p) *________p1 = (typeof(*p) *__force)lockless_dereference(p); \ | ||
| 586 | rcu_lockdep_assert(c, "suspicious rcu_dereference_check() usage"); \ | 588 | rcu_lockdep_assert(c, "suspicious rcu_dereference_check() usage"); \ |
| 587 | rcu_dereference_sparse(p, space); \ | 589 | rcu_dereference_sparse(p, space); \ |
| 588 | smp_read_barrier_depends(); /* Dependency order vs. p above. */ \ | 590 | ((typeof(*p) __force __kernel *)(________p1)); \ |
| 589 | ((typeof(*p) __force __kernel *)(_________p1)); \ | ||
| 590 | }) | 591 | }) |
| 591 | #define __rcu_dereference_protected(p, c, space) \ | 592 | #define __rcu_dereference_protected(p, c, space) \ |
| 592 | ({ \ | 593 | ({ \ |
| @@ -603,10 +604,10 @@ static inline void rcu_preempt_sleep_check(void) | |||
| 603 | }) | 604 | }) |
| 604 | #define __rcu_dereference_index_check(p, c) \ | 605 | #define __rcu_dereference_index_check(p, c) \ |
| 605 | ({ \ | 606 | ({ \ |
| 606 | typeof(p) _________p1 = ACCESS_ONCE(p); \ | 607 | /* Dependency order vs. p above. */ \ |
| 608 | typeof(p) _________p1 = lockless_dereference(p); \ | ||
| 607 | rcu_lockdep_assert(c, \ | 609 | rcu_lockdep_assert(c, \ |
| 608 | "suspicious rcu_dereference_index_check() usage"); \ | 610 | "suspicious rcu_dereference_index_check() usage"); \ |
| 609 | smp_read_barrier_depends(); /* Dependency order vs. p above. */ \ | ||
| 610 | (_________p1); \ | 611 | (_________p1); \ |
| 611 | }) | 612 | }) |
| 612 | 613 | ||
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h index 0e5366200154..937edaeb150d 100644 --- a/include/linux/rcutiny.h +++ b/include/linux/rcutiny.h | |||
| @@ -92,17 +92,49 @@ static inline void rcu_virt_note_context_switch(int cpu) | |||
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | /* | 94 | /* |
| 95 | * Return the number of grace periods. | 95 | * Return the number of grace periods started. |
| 96 | */ | 96 | */ |
| 97 | static inline long rcu_batches_completed(void) | 97 | static inline unsigned long rcu_batches_started(void) |
| 98 | { | 98 | { |
| 99 | return 0; | 99 | return 0; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | /* | 102 | /* |
| 103 | * Return the number of bottom-half grace periods. | 103 | * Return the number of bottom-half grace periods started. |
| 104 | */ | 104 | */ |
| 105 | static inline long rcu_batches_completed_bh(void) | 105 | static inline unsigned long rcu_batches_started_bh(void) |
| 106 | { | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Return the number of sched grace periods started. | ||
| 112 | */ | ||
| 113 | static inline unsigned long rcu_batches_started_sched(void) | ||
| 114 | { | ||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | /* | ||
| 119 | * Return the number of grace periods completed. | ||
| 120 | */ | ||
| 121 | static inline unsigned long rcu_batches_completed(void) | ||
| 122 | { | ||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Return the number of bottom-half grace periods completed. | ||
| 128 | */ | ||
| 129 | static inline unsigned long rcu_batches_completed_bh(void) | ||
| 130 | { | ||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | /* | ||
| 135 | * Return the number of sched grace periods completed. | ||
| 136 | */ | ||
| 137 | static inline unsigned long rcu_batches_completed_sched(void) | ||
| 106 | { | 138 | { |
| 107 | return 0; | 139 | return 0; |
| 108 | } | 140 | } |
| @@ -154,7 +186,10 @@ static inline bool rcu_is_watching(void) | |||
| 154 | return true; | 186 | return true; |
| 155 | } | 187 | } |
| 156 | 188 | ||
| 157 | |||
| 158 | #endif /* #else defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) */ | 189 | #endif /* #else defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) */ |
| 159 | 190 | ||
| 191 | static inline void rcu_all_qs(void) | ||
| 192 | { | ||
| 193 | } | ||
| 194 | |||
| 160 | #endif /* __LINUX_RCUTINY_H */ | 195 | #endif /* __LINUX_RCUTINY_H */ |
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index 52953790dcca..d2e583a6aaca 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h | |||
| @@ -81,9 +81,12 @@ void cond_synchronize_rcu(unsigned long oldstate); | |||
| 81 | 81 | ||
| 82 | extern unsigned long rcutorture_testseq; | 82 | extern unsigned long rcutorture_testseq; |
| 83 | extern unsigned long rcutorture_vernum; | 83 | extern unsigned long rcutorture_vernum; |
| 84 | long rcu_batches_completed(void); | 84 | unsigned long rcu_batches_started(void); |
| 85 | long rcu_batches_completed_bh(void); | 85 | unsigned long rcu_batches_started_bh(void); |
| 86 | long rcu_batches_completed_sched(void); | 86 | unsigned long rcu_batches_started_sched(void); |
| 87 | unsigned long rcu_batches_completed(void); | ||
| 88 | unsigned long rcu_batches_completed_bh(void); | ||
| 89 | unsigned long rcu_batches_completed_sched(void); | ||
| 87 | void show_rcu_gp_kthreads(void); | 90 | void show_rcu_gp_kthreads(void); |
| 88 | 91 | ||
| 89 | void rcu_force_quiescent_state(void); | 92 | void rcu_force_quiescent_state(void); |
| @@ -97,4 +100,6 @@ extern int rcu_scheduler_active __read_mostly; | |||
| 97 | 100 | ||
| 98 | bool rcu_is_watching(void); | 101 | bool rcu_is_watching(void); |
| 99 | 102 | ||
| 103 | void rcu_all_qs(void); | ||
| 104 | |||
| 100 | #endif /* __LINUX_RCUTREE_H */ | 105 | #endif /* __LINUX_RCUTREE_H */ |
diff --git a/include/linux/srcu.h b/include/linux/srcu.h index a2783cb5d275..9cfd9623fb03 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h | |||
| @@ -45,7 +45,7 @@ struct rcu_batch { | |||
| 45 | #define RCU_BATCH_INIT(name) { NULL, &(name.head) } | 45 | #define RCU_BATCH_INIT(name) { NULL, &(name.head) } |
| 46 | 46 | ||
| 47 | struct srcu_struct { | 47 | struct srcu_struct { |
| 48 | unsigned completed; | 48 | unsigned long completed; |
| 49 | struct srcu_struct_array __percpu *per_cpu_ref; | 49 | struct srcu_struct_array __percpu *per_cpu_ref; |
| 50 | spinlock_t queue_lock; /* protect ->batch_queue, ->running */ | 50 | spinlock_t queue_lock; /* protect ->batch_queue, ->running */ |
| 51 | bool running; | 51 | bool running; |
| @@ -102,13 +102,11 @@ void process_srcu(struct work_struct *work); | |||
| 102 | * define and init a srcu struct at build time. | 102 | * define and init a srcu struct at build time. |
| 103 | * dont't call init_srcu_struct() nor cleanup_srcu_struct() on it. | 103 | * dont't call init_srcu_struct() nor cleanup_srcu_struct() on it. |
| 104 | */ | 104 | */ |
| 105 | #define DEFINE_SRCU(name) \ | 105 | #define __DEFINE_SRCU(name, is_static) \ |
| 106 | static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\ | 106 | static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\ |
| 107 | struct srcu_struct name = __SRCU_STRUCT_INIT(name); | 107 | is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name) |
| 108 | 108 | #define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */) | |
| 109 | #define DEFINE_STATIC_SRCU(name) \ | 109 | #define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static) |
| 110 | static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\ | ||
| 111 | static struct srcu_struct name = __SRCU_STRUCT_INIT(name); | ||
| 112 | 110 | ||
| 113 | /** | 111 | /** |
| 114 | * call_srcu() - Queue a callback for invocation after an SRCU grace period | 112 | * call_srcu() - Queue a callback for invocation after an SRCU grace period |
| @@ -135,7 +133,7 @@ int __srcu_read_lock(struct srcu_struct *sp) __acquires(sp); | |||
| 135 | void __srcu_read_unlock(struct srcu_struct *sp, int idx) __releases(sp); | 133 | void __srcu_read_unlock(struct srcu_struct *sp, int idx) __releases(sp); |
| 136 | void synchronize_srcu(struct srcu_struct *sp); | 134 | void synchronize_srcu(struct srcu_struct *sp); |
| 137 | void synchronize_srcu_expedited(struct srcu_struct *sp); | 135 | void synchronize_srcu_expedited(struct srcu_struct *sp); |
| 138 | long srcu_batches_completed(struct srcu_struct *sp); | 136 | unsigned long srcu_batches_completed(struct srcu_struct *sp); |
| 139 | void srcu_barrier(struct srcu_struct *sp); | 137 | void srcu_barrier(struct srcu_struct *sp); |
| 140 | 138 | ||
| 141 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 139 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
