Loading Documentation/RCU/rcu_dereference.txt +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ o You must use one of the rcu_dereference() family of primitives o Avoid cancellation when using the "+" and "-" infix arithmetic operators. For example, for a given variable "x", avoid "(x-x)". There are similar arithmetic pitfalls from other arithmetic operatiors, such as "(x*0)", "(x/(x+1))" or "(x%1)". arithmetic operators, such as "(x*0)", "(x/(x+1))" or "(x%1)". The compiler is within its rights to substitute zero for all of these expressions, so that subsequent accesses no longer depend on the rcu_dereference(), again possibly resulting in bugs due Loading Documentation/kernel-parameters.txt +24 −11 Original line number Diff line number Diff line Loading @@ -3135,22 +3135,35 @@ bytes respectively. Such letter suffixes can also be entirely omitted. in a given burst of a callback-flood test. rcutorture.fqs_duration= [KNL] Set duration of force_quiescent_state bursts. Set duration of force_quiescent_state bursts in microseconds. rcutorture.fqs_holdoff= [KNL] Set holdoff time within force_quiescent_state bursts. Set holdoff time within force_quiescent_state bursts in microseconds. rcutorture.fqs_stutter= [KNL] Set wait time between force_quiescent_state bursts. Set wait time between force_quiescent_state bursts in seconds. rcutorture.gp_cond= [KNL] Use conditional/asynchronous update-side primitives, if available. rcutorture.gp_exp= [KNL] Use expedited update-side primitives. Use expedited update-side primitives, if available. rcutorture.gp_normal= [KNL] Use normal (non-expedited) update-side primitives. If both gp_exp and gp_normal are set, do both. If neither gp_exp nor gp_normal are set, still do both. Use normal (non-expedited) asynchronous update-side primitives, if available. rcutorture.gp_sync= [KNL] Use normal (non-expedited) synchronous update-side primitives, if available. If all of rcutorture.gp_cond=, rcutorture.gp_exp=, rcutorture.gp_normal=, and rcutorture.gp_sync= are zero, rcutorture acts as if is interpreted they are all non-zero. rcutorture.n_barrier_cbs= [KNL] Set callbacks/threads for rcu_barrier() testing. Loading @@ -3177,9 +3190,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Set time (s) between CPU-hotplug operations, or zero to disable CPU-hotplug testing. rcutorture.torture_runnable= [BOOT] Start rcutorture running at boot time. rcutorture.shuffle_interval= [KNL] Set task-shuffle interval (s). Shuffling tasks allows some CPUs to go into dyntick-idle mode Loading Loading @@ -3220,6 +3230,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Test RCU's dyntick-idle handling. See also the rcutorture.shuffle_interval parameter. rcutorture.torture_runnable= [BOOT] Start rcutorture running at boot time. rcutorture.torture_type= [KNL] Specify the RCU implementation to test. Loading Documentation/memory-barriers.txt +184 −175 File changed.Preview size limit exceeded, changes collapsed. Show changes kernel/rcu/rcutorture.c +27 −13 Original line number Diff line number Diff line Loading @@ -686,10 +686,20 @@ static struct rcu_torture_ops tasks_ops = { #define RCUTORTURE_TASKS_OPS &tasks_ops, static bool __maybe_unused torturing_tasks(void) { return cur_ops == &tasks_ops; } #else /* #ifdef CONFIG_TASKS_RCU */ #define RCUTORTURE_TASKS_OPS static bool torturing_tasks(void) { return false; } #endif /* #else #ifdef CONFIG_TASKS_RCU */ /* Loading Loading @@ -825,9 +835,7 @@ rcu_torture_cbflood(void *arg) } if (err) { VERBOSE_TOROUT_STRING("rcu_torture_cbflood disabled: Bad args or OOM"); while (!torture_must_stop()) schedule_timeout_interruptible(HZ); return 0; goto wait_for_stop; } VERBOSE_TOROUT_STRING("rcu_torture_cbflood task started"); do { Loading @@ -846,6 +854,7 @@ rcu_torture_cbflood(void *arg) stutter_wait("rcu_torture_cbflood"); } while (!torture_must_stop()); vfree(rhp); wait_for_stop: torture_kthread_stopping("rcu_torture_cbflood"); return 0; } Loading Loading @@ -1090,7 +1099,8 @@ static void rcu_torture_timer(unsigned long unused) p = rcu_dereference_check(rcu_torture_current, rcu_read_lock_bh_held() || rcu_read_lock_sched_held() || srcu_read_lock_held(srcu_ctlp)); srcu_read_lock_held(srcu_ctlp) || torturing_tasks()); if (p == NULL) { /* Leave because rcu_torture_writer is not yet underway */ cur_ops->readunlock(idx); Loading Loading @@ -1164,7 +1174,8 @@ rcu_torture_reader(void *arg) p = rcu_dereference_check(rcu_torture_current, rcu_read_lock_bh_held() || rcu_read_lock_sched_held() || srcu_read_lock_held(srcu_ctlp)); srcu_read_lock_held(srcu_ctlp) || torturing_tasks()); if (p == NULL) { /* Wait for rcu_torture_writer to get underway */ cur_ops->readunlock(idx); Loading Loading @@ -1509,7 +1520,7 @@ static int rcu_torture_barrier_init(void) int i; int ret; if (n_barrier_cbs == 0) if (n_barrier_cbs <= 0) return 0; if (cur_ops->call == NULL || cur_ops->cb_barrier == NULL) { pr_alert("%s" TORTURE_FLAG Loading Loading @@ -1788,13 +1799,16 @@ rcu_torture_init(void) writer_task); if (firsterr) goto unwind; fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]), if (nfakewriters > 0) { fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]), GFP_KERNEL); if (fakewriter_tasks == NULL) { VERBOSE_TOROUT_ERRSTRING("out of memory"); firsterr = -ENOMEM; goto unwind; } } for (i = 0; i < nfakewriters; i++) { firsterr = torture_create_kthread(rcu_torture_fakewriter, NULL, fakewriter_tasks[i]); Loading @@ -1820,7 +1834,7 @@ rcu_torture_init(void) if (firsterr) goto unwind; } if (test_no_idle_hz) { if (test_no_idle_hz && shuffle_interval > 0) { firsterr = torture_shuffle_init(shuffle_interval * HZ); if (firsterr) goto unwind; Loading tools/testing/selftests/rcutorture/configs/rcu/TASKS01 +2 −2 Original line number Diff line number Diff line Loading @@ -5,6 +5,6 @@ CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=y CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_PROVE_LOCKING=n #CHECK#CONFIG_PROVE_RCU=n CONFIG_PROVE_LOCKING=y #CHECK#CONFIG_PROVE_RCU=y CONFIG_RCU_EXPERT=y Loading
Documentation/RCU/rcu_dereference.txt +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ o You must use one of the rcu_dereference() family of primitives o Avoid cancellation when using the "+" and "-" infix arithmetic operators. For example, for a given variable "x", avoid "(x-x)". There are similar arithmetic pitfalls from other arithmetic operatiors, such as "(x*0)", "(x/(x+1))" or "(x%1)". arithmetic operators, such as "(x*0)", "(x/(x+1))" or "(x%1)". The compiler is within its rights to substitute zero for all of these expressions, so that subsequent accesses no longer depend on the rcu_dereference(), again possibly resulting in bugs due Loading
Documentation/kernel-parameters.txt +24 −11 Original line number Diff line number Diff line Loading @@ -3135,22 +3135,35 @@ bytes respectively. Such letter suffixes can also be entirely omitted. in a given burst of a callback-flood test. rcutorture.fqs_duration= [KNL] Set duration of force_quiescent_state bursts. Set duration of force_quiescent_state bursts in microseconds. rcutorture.fqs_holdoff= [KNL] Set holdoff time within force_quiescent_state bursts. Set holdoff time within force_quiescent_state bursts in microseconds. rcutorture.fqs_stutter= [KNL] Set wait time between force_quiescent_state bursts. Set wait time between force_quiescent_state bursts in seconds. rcutorture.gp_cond= [KNL] Use conditional/asynchronous update-side primitives, if available. rcutorture.gp_exp= [KNL] Use expedited update-side primitives. Use expedited update-side primitives, if available. rcutorture.gp_normal= [KNL] Use normal (non-expedited) update-side primitives. If both gp_exp and gp_normal are set, do both. If neither gp_exp nor gp_normal are set, still do both. Use normal (non-expedited) asynchronous update-side primitives, if available. rcutorture.gp_sync= [KNL] Use normal (non-expedited) synchronous update-side primitives, if available. If all of rcutorture.gp_cond=, rcutorture.gp_exp=, rcutorture.gp_normal=, and rcutorture.gp_sync= are zero, rcutorture acts as if is interpreted they are all non-zero. rcutorture.n_barrier_cbs= [KNL] Set callbacks/threads for rcu_barrier() testing. Loading @@ -3177,9 +3190,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Set time (s) between CPU-hotplug operations, or zero to disable CPU-hotplug testing. rcutorture.torture_runnable= [BOOT] Start rcutorture running at boot time. rcutorture.shuffle_interval= [KNL] Set task-shuffle interval (s). Shuffling tasks allows some CPUs to go into dyntick-idle mode Loading Loading @@ -3220,6 +3230,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Test RCU's dyntick-idle handling. See also the rcutorture.shuffle_interval parameter. rcutorture.torture_runnable= [BOOT] Start rcutorture running at boot time. rcutorture.torture_type= [KNL] Specify the RCU implementation to test. Loading
Documentation/memory-barriers.txt +184 −175 File changed.Preview size limit exceeded, changes collapsed. Show changes
kernel/rcu/rcutorture.c +27 −13 Original line number Diff line number Diff line Loading @@ -686,10 +686,20 @@ static struct rcu_torture_ops tasks_ops = { #define RCUTORTURE_TASKS_OPS &tasks_ops, static bool __maybe_unused torturing_tasks(void) { return cur_ops == &tasks_ops; } #else /* #ifdef CONFIG_TASKS_RCU */ #define RCUTORTURE_TASKS_OPS static bool torturing_tasks(void) { return false; } #endif /* #else #ifdef CONFIG_TASKS_RCU */ /* Loading Loading @@ -825,9 +835,7 @@ rcu_torture_cbflood(void *arg) } if (err) { VERBOSE_TOROUT_STRING("rcu_torture_cbflood disabled: Bad args or OOM"); while (!torture_must_stop()) schedule_timeout_interruptible(HZ); return 0; goto wait_for_stop; } VERBOSE_TOROUT_STRING("rcu_torture_cbflood task started"); do { Loading @@ -846,6 +854,7 @@ rcu_torture_cbflood(void *arg) stutter_wait("rcu_torture_cbflood"); } while (!torture_must_stop()); vfree(rhp); wait_for_stop: torture_kthread_stopping("rcu_torture_cbflood"); return 0; } Loading Loading @@ -1090,7 +1099,8 @@ static void rcu_torture_timer(unsigned long unused) p = rcu_dereference_check(rcu_torture_current, rcu_read_lock_bh_held() || rcu_read_lock_sched_held() || srcu_read_lock_held(srcu_ctlp)); srcu_read_lock_held(srcu_ctlp) || torturing_tasks()); if (p == NULL) { /* Leave because rcu_torture_writer is not yet underway */ cur_ops->readunlock(idx); Loading Loading @@ -1164,7 +1174,8 @@ rcu_torture_reader(void *arg) p = rcu_dereference_check(rcu_torture_current, rcu_read_lock_bh_held() || rcu_read_lock_sched_held() || srcu_read_lock_held(srcu_ctlp)); srcu_read_lock_held(srcu_ctlp) || torturing_tasks()); if (p == NULL) { /* Wait for rcu_torture_writer to get underway */ cur_ops->readunlock(idx); Loading Loading @@ -1509,7 +1520,7 @@ static int rcu_torture_barrier_init(void) int i; int ret; if (n_barrier_cbs == 0) if (n_barrier_cbs <= 0) return 0; if (cur_ops->call == NULL || cur_ops->cb_barrier == NULL) { pr_alert("%s" TORTURE_FLAG Loading Loading @@ -1788,13 +1799,16 @@ rcu_torture_init(void) writer_task); if (firsterr) goto unwind; fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]), if (nfakewriters > 0) { fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]), GFP_KERNEL); if (fakewriter_tasks == NULL) { VERBOSE_TOROUT_ERRSTRING("out of memory"); firsterr = -ENOMEM; goto unwind; } } for (i = 0; i < nfakewriters; i++) { firsterr = torture_create_kthread(rcu_torture_fakewriter, NULL, fakewriter_tasks[i]); Loading @@ -1820,7 +1834,7 @@ rcu_torture_init(void) if (firsterr) goto unwind; } if (test_no_idle_hz) { if (test_no_idle_hz && shuffle_interval > 0) { firsterr = torture_shuffle_init(shuffle_interval * HZ); if (firsterr) goto unwind; Loading
tools/testing/selftests/rcutorture/configs/rcu/TASKS01 +2 −2 Original line number Diff line number Diff line Loading @@ -5,6 +5,6 @@ CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=y CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_PROVE_LOCKING=n #CHECK#CONFIG_PROVE_RCU=n CONFIG_PROVE_LOCKING=y #CHECK#CONFIG_PROVE_RCU=y CONFIG_RCU_EXPERT=y