diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-03 15:35:05 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-03 15:35:05 -0400 |
| commit | 59a3d4c3631e553357b7305dc09db1990aa6757c (patch) | |
| tree | 7c55a2447dc7175d8701c600e5536e4a18d8388b /include | |
| parent | ff806d034ef8e9a95ff0b0532104dd65332e446b (diff) | |
| parent | e14505a8d50882ff3bdd4b791b14d90a0881fa4d (diff) | |
Merge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into next
Pull RCU changes from Ingo Molnar:
"The main RCU changes in this cycle were:
- RCU torture-test changes.
- variable-name renaming cleanup.
- update RCU documentation.
- miscellaneous fixes.
- patch to suppress RCU stall warnings while sysrq requests are being
processed"
* 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (68 commits)
rcu: Provide API to suppress stall warnings while sysrc runs
rcu: Variable name changed in tree_plugin.h and used in tree.c
torture: Remove unused definition
torture: Remove __init from torture_init_begin/end
torture: Check for multiple concurrent torture tests
locktorture: Remove reference to nonexistent Kconfig parameter
rcutorture: Run rcu_torture_writer at normal priority
rcutorture: Note diffs from git commits
rcutorture: Add missing destroy_timer_on_stack()
rcutorture: Explicitly test synchronous grace-period primitives
rcutorture: Add tests for get_state_synchronize_rcu()
rcutorture: Test RCU-sched primitives in TREE_PREEMPT_RCU kernels
torture: Use elapsed time to detect hangs
rcutorture: Check for rcu_torture_fqs creation errors
torture: Better summary diagnostics for build failures
torture: Notice if an all-zero cpumask is passed inside a critical section
rcutorture: Make rcu_torture_reader() use cond_resched()
sched,rcu: Make cond_resched() report RCU quiescent states
percpu: Fix raw_cpu_inc_return()
rcutorture: Export RCU grace-period kthread wait state to rcutorture
...
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/percpu.h | 2 | ||||
| -rw-r--r-- | include/linux/rcupdate.h | 72 | ||||
| -rw-r--r-- | include/linux/rcutiny.h | 4 | ||||
| -rw-r--r-- | include/linux/rcutree.h | 1 | ||||
| -rw-r--r-- | include/linux/torture.h | 8 |
5 files changed, 78 insertions, 9 deletions
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index e7a0b95ed527..495c6543a8f2 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
| @@ -639,7 +639,7 @@ do { \ | |||
| 639 | # define raw_cpu_add_return_8(pcp, val) raw_cpu_generic_add_return(pcp, val) | 639 | # define raw_cpu_add_return_8(pcp, val) raw_cpu_generic_add_return(pcp, val) |
| 640 | # endif | 640 | # endif |
| 641 | # define raw_cpu_add_return(pcp, val) \ | 641 | # define raw_cpu_add_return(pcp, val) \ |
| 642 | __pcpu_size_call_return2(raw_add_return_, pcp, val) | 642 | __pcpu_size_call_return2(raw_cpu_add_return_, pcp, val) |
| 643 | #endif | 643 | #endif |
| 644 | 644 | ||
| 645 | #define raw_cpu_sub_return(pcp, val) raw_cpu_add_return(pcp, -(typeof(pcp))(val)) | 645 | #define raw_cpu_sub_return(pcp, val) raw_cpu_add_return(pcp, -(typeof(pcp))(val)) |
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 00a7fd61b3c6..5a75d19aa661 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <linux/debugobjects.h> | 44 | #include <linux/debugobjects.h> |
| 45 | #include <linux/bug.h> | 45 | #include <linux/bug.h> |
| 46 | #include <linux/compiler.h> | 46 | #include <linux/compiler.h> |
| 47 | #include <linux/percpu.h> | ||
| 47 | #include <asm/barrier.h> | 48 | #include <asm/barrier.h> |
| 48 | 49 | ||
| 49 | extern int rcu_expedited; /* for sysctl */ | 50 | extern int rcu_expedited; /* for sysctl */ |
| @@ -51,7 +52,17 @@ extern int rcu_expedited; /* for sysctl */ | |||
| 51 | extern int rcutorture_runnable; /* for sysctl */ | 52 | extern int rcutorture_runnable; /* for sysctl */ |
| 52 | #endif /* #ifdef CONFIG_RCU_TORTURE_TEST */ | 53 | #endif /* #ifdef CONFIG_RCU_TORTURE_TEST */ |
| 53 | 54 | ||
| 55 | enum rcutorture_type { | ||
| 56 | RCU_FLAVOR, | ||
| 57 | RCU_BH_FLAVOR, | ||
| 58 | RCU_SCHED_FLAVOR, | ||
| 59 | SRCU_FLAVOR, | ||
| 60 | INVALID_RCU_FLAVOR | ||
| 61 | }; | ||
| 62 | |||
| 54 | #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) | 63 | #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) |
| 64 | void rcutorture_get_gp_data(enum rcutorture_type test_type, int *flags, | ||
| 65 | unsigned long *gpnum, unsigned long *completed); | ||
| 55 | void rcutorture_record_test_transition(void); | 66 | void rcutorture_record_test_transition(void); |
| 56 | void rcutorture_record_progress(unsigned long vernum); | 67 | void rcutorture_record_progress(unsigned long vernum); |
| 57 | void do_trace_rcu_torture_read(const char *rcutorturename, | 68 | void do_trace_rcu_torture_read(const char *rcutorturename, |
| @@ -60,6 +71,15 @@ void do_trace_rcu_torture_read(const char *rcutorturename, | |||
| 60 | unsigned long c_old, | 71 | unsigned long c_old, |
| 61 | unsigned long c); | 72 | unsigned long c); |
| 62 | #else | 73 | #else |
| 74 | static inline void rcutorture_get_gp_data(enum rcutorture_type test_type, | ||
| 75 | int *flags, | ||
| 76 | unsigned long *gpnum, | ||
| 77 | unsigned long *completed) | ||
| 78 | { | ||
| 79 | *flags = 0; | ||
| 80 | *gpnum = 0; | ||
| 81 | *completed = 0; | ||
| 82 | } | ||
| 63 | static inline void rcutorture_record_test_transition(void) | 83 | static inline void rcutorture_record_test_transition(void) |
| 64 | { | 84 | { |
| 65 | } | 85 | } |
| @@ -228,6 +248,18 @@ void rcu_idle_exit(void); | |||
| 228 | void rcu_irq_enter(void); | 248 | void rcu_irq_enter(void); |
| 229 | void rcu_irq_exit(void); | 249 | void rcu_irq_exit(void); |
| 230 | 250 | ||
| 251 | #ifdef CONFIG_RCU_STALL_COMMON | ||
| 252 | void rcu_sysrq_start(void); | ||
| 253 | void rcu_sysrq_end(void); | ||
| 254 | #else /* #ifdef CONFIG_RCU_STALL_COMMON */ | ||
| 255 | static inline void rcu_sysrq_start(void) | ||
| 256 | { | ||
| 257 | } | ||
| 258 | static inline void rcu_sysrq_end(void) | ||
| 259 | { | ||
| 260 | } | ||
| 261 | #endif /* #else #ifdef CONFIG_RCU_STALL_COMMON */ | ||
| 262 | |||
| 231 | #ifdef CONFIG_RCU_USER_QS | 263 | #ifdef CONFIG_RCU_USER_QS |
| 232 | void rcu_user_enter(void); | 264 | void rcu_user_enter(void); |
| 233 | void rcu_user_exit(void); | 265 | void rcu_user_exit(void); |
| @@ -268,6 +300,41 @@ bool __rcu_is_watching(void); | |||
| 268 | #endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) || defined(CONFIG_SMP) */ | 300 | #endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) || defined(CONFIG_SMP) */ |
| 269 | 301 | ||
| 270 | /* | 302 | /* |
| 303 | * Hooks for cond_resched() and friends to avoid RCU CPU stall warnings. | ||
| 304 | */ | ||
| 305 | |||
| 306 | #define RCU_COND_RESCHED_LIM 256 /* ms vs. 100s of ms. */ | ||
| 307 | DECLARE_PER_CPU(int, rcu_cond_resched_count); | ||
| 308 | void rcu_resched(void); | ||
| 309 | |||
| 310 | /* | ||
| 311 | * Is it time to report RCU quiescent states? | ||
| 312 | * | ||
| 313 | * Note unsynchronized access to rcu_cond_resched_count. Yes, we might | ||
| 314 | * increment some random CPU's count, and possibly also load the result from | ||
| 315 | * yet another CPU's count. We might even clobber some other CPU's attempt | ||
| 316 | * to zero its counter. This is all OK because the goal is not precision, | ||
| 317 | * but rather reasonable amortization of rcu_note_context_switch() overhead | ||
| 318 | * and extremely high probability of avoiding RCU CPU stall warnings. | ||
| 319 | * Note that this function has to be preempted in just the wrong place, | ||
| 320 | * many thousands of times in a row, for anything bad to happen. | ||
| 321 | */ | ||
| 322 | static inline bool rcu_should_resched(void) | ||
| 323 | { | ||
| 324 | return raw_cpu_inc_return(rcu_cond_resched_count) >= | ||
| 325 | RCU_COND_RESCHED_LIM; | ||
| 326 | } | ||
| 327 | |||
| 328 | /* | ||
| 329 | * Report quiscent states to RCU if it is time to do so. | ||
| 330 | */ | ||
| 331 | static inline void rcu_cond_resched(void) | ||
| 332 | { | ||
| 333 | if (unlikely(rcu_should_resched())) | ||
| 334 | rcu_resched(); | ||
| 335 | } | ||
| 336 | |||
| 337 | /* | ||
| 271 | * Infrastructure to implement the synchronize_() primitives in | 338 | * Infrastructure to implement the synchronize_() primitives in |
| 272 | * TREE_RCU and rcu_barrier_() primitives in TINY_RCU. | 339 | * TREE_RCU and rcu_barrier_() primitives in TINY_RCU. |
| 273 | */ | 340 | */ |
| @@ -328,7 +395,7 @@ extern struct lockdep_map rcu_lock_map; | |||
| 328 | extern struct lockdep_map rcu_bh_lock_map; | 395 | extern struct lockdep_map rcu_bh_lock_map; |
| 329 | extern struct lockdep_map rcu_sched_lock_map; | 396 | extern struct lockdep_map rcu_sched_lock_map; |
| 330 | extern struct lockdep_map rcu_callback_map; | 397 | extern struct lockdep_map rcu_callback_map; |
| 331 | extern int debug_lockdep_rcu_enabled(void); | 398 | int debug_lockdep_rcu_enabled(void); |
| 332 | 399 | ||
| 333 | /** | 400 | /** |
| 334 | * rcu_read_lock_held() - might we be in RCU read-side critical section? | 401 | * rcu_read_lock_held() - might we be in RCU read-side critical section? |
| @@ -949,6 +1016,9 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
| 949 | * pointers, but you must use rcu_assign_pointer() to initialize the | 1016 | * pointers, but you must use rcu_assign_pointer() to initialize the |
| 950 | * external-to-structure pointer -after- you have completely initialized | 1017 | * external-to-structure pointer -after- you have completely initialized |
| 951 | * the reader-accessible portions of the linked structure. | 1018 | * the reader-accessible portions of the linked structure. |
| 1019 | * | ||
| 1020 | * Note that unlike rcu_assign_pointer(), RCU_INIT_POINTER() provides no | ||
| 1021 | * ordering guarantees for either the CPU or the compiler. | ||
| 952 | */ | 1022 | */ |
| 953 | #define RCU_INIT_POINTER(p, v) \ | 1023 | #define RCU_INIT_POINTER(p, v) \ |
| 954 | do { \ | 1024 | do { \ |
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h index 425c659d54e5..d40a6a451330 100644 --- a/include/linux/rcutiny.h +++ b/include/linux/rcutiny.h | |||
| @@ -119,6 +119,10 @@ static inline void rcu_sched_force_quiescent_state(void) | |||
| 119 | { | 119 | { |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | static inline void show_rcu_gp_kthreads(void) | ||
| 123 | { | ||
| 124 | } | ||
| 125 | |||
| 122 | static inline void rcu_cpu_stall_reset(void) | 126 | static inline void rcu_cpu_stall_reset(void) |
| 123 | { | 127 | { |
| 124 | } | 128 | } |
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index a59ca05fd4e3..3e2f5d432743 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h | |||
| @@ -84,6 +84,7 @@ extern unsigned long rcutorture_vernum; | |||
| 84 | long rcu_batches_completed(void); | 84 | long rcu_batches_completed(void); |
| 85 | long rcu_batches_completed_bh(void); | 85 | long rcu_batches_completed_bh(void); |
| 86 | long rcu_batches_completed_sched(void); | 86 | long rcu_batches_completed_sched(void); |
| 87 | void show_rcu_gp_kthreads(void); | ||
| 87 | 88 | ||
| 88 | void rcu_force_quiescent_state(void); | 89 | void rcu_force_quiescent_state(void); |
| 89 | void rcu_bh_force_quiescent_state(void); | 90 | void rcu_bh_force_quiescent_state(void); |
diff --git a/include/linux/torture.h b/include/linux/torture.h index b2e2b468e511..5ca58fcbaf1b 100644 --- a/include/linux/torture.h +++ b/include/linux/torture.h | |||
| @@ -49,12 +49,6 @@ | |||
| 49 | #define VERBOSE_TOROUT_ERRSTRING(s) \ | 49 | #define VERBOSE_TOROUT_ERRSTRING(s) \ |
| 50 | do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! %s\n", torture_type, s); } while (0) | 50 | do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! %s\n", torture_type, s); } while (0) |
| 51 | 51 | ||
| 52 | /* Definitions for a non-string torture-test module parameter. */ | ||
| 53 | #define torture_parm(type, name, init, msg) \ | ||
| 54 | static type name = init; \ | ||
| 55 | module_param(name, type, 0444); \ | ||
| 56 | MODULE_PARM_DESC(name, msg); | ||
| 57 | |||
| 58 | /* Definitions for online/offline exerciser. */ | 52 | /* Definitions for online/offline exerciser. */ |
| 59 | int torture_onoff_init(long ooholdoff, long oointerval); | 53 | int torture_onoff_init(long ooholdoff, long oointerval); |
| 60 | char *torture_onoff_stats(char *page); | 54 | char *torture_onoff_stats(char *page); |
| @@ -81,7 +75,7 @@ void stutter_wait(const char *title); | |||
| 81 | int torture_stutter_init(int s); | 75 | int torture_stutter_init(int s); |
| 82 | 76 | ||
| 83 | /* Initialization and cleanup. */ | 77 | /* Initialization and cleanup. */ |
| 84 | void torture_init_begin(char *ttype, bool v, int *runnable); | 78 | bool torture_init_begin(char *ttype, bool v, int *runnable); |
| 85 | void torture_init_end(void); | 79 | void torture_init_end(void); |
| 86 | bool torture_cleanup(void); | 80 | bool torture_cleanup(void); |
| 87 | bool torture_must_stop(void); | 81 | bool torture_must_stop(void); |
