summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2018-08-07 17:34:44 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2018-08-29 12:20:48 -0400
commit474e59b476b3390ef9f730515439f21640b61623 (patch)
treebcbd93a01c459c55c5df6cd4d469d96cdc9e1c82
parentf4de46ed5bbc8ba9acebc8ac75809751b716e470 (diff)
rcutorture: Check GP completion at stutter end
The rcu_torture_writer() function invokes stutter_wait() at the end of each writer pass, which occasionally blocks for an extended time period in order to ensure that RCU can handle intermittent loads. But part of handling a busy period is invoking all the callbacks before the end of the idle period induced by stutter_wait(). This commit therefore adds a return value to stutter_wait() indicating whether stutter_wait() actually waited. In addition, this commit causes rcu_torture_writer() to test this value and if set, checks that all the elements of the rcu_tortures[] array have been freed up. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r--include/linux/torture.h2
-rw-r--r--kernel/rcu/rcutorture.c5
-rw-r--r--kernel/torture.c3
3 files changed, 7 insertions, 3 deletions
diff --git a/include/linux/torture.h b/include/linux/torture.h
index 61dfd93b6ee4..48fad21109fc 100644
--- a/include/linux/torture.h
+++ b/include/linux/torture.h
@@ -77,7 +77,7 @@ void torture_shutdown_absorb(const char *title);
77int torture_shutdown_init(int ssecs, void (*cleanup)(void)); 77int torture_shutdown_init(int ssecs, void (*cleanup)(void));
78 78
79/* Task stuttering, which forces load/no-load transitions. */ 79/* Task stuttering, which forces load/no-load transitions. */
80void stutter_wait(const char *title); 80bool stutter_wait(const char *title);
81int torture_stutter_init(int s); 81int torture_stutter_init(int s);
82 82
83/* Initialization and cleanup. */ 83/* Initialization and cleanup. */
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 7df8142a6a22..ae10ad531993 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1144,7 +1144,10 @@ rcu_torture_writer(void *arg)
1144 !rcu_gp_is_normal(); 1144 !rcu_gp_is_normal();
1145 } 1145 }
1146 rcu_torture_writer_state = RTWS_STUTTER; 1146 rcu_torture_writer_state = RTWS_STUTTER;
1147 stutter_wait("rcu_torture_writer"); 1147 if (stutter_wait("rcu_torture_writer"))
1148 for (i = 0; i < ARRAY_SIZE(rcu_tortures); i++)
1149 if (list_empty(&rcu_tortures[i].rtort_free))
1150 WARN_ON_ONCE(1);
1148 } while (!torture_must_stop()); 1151 } while (!torture_must_stop());
1149 /* Reset expediting back to unexpedited. */ 1152 /* Reset expediting back to unexpedited. */
1150 if (expediting > 0) 1153 if (expediting > 0)
diff --git a/kernel/torture.c b/kernel/torture.c
index 1ac24a826589..17d91f5fba2a 100644
--- a/kernel/torture.c
+++ b/kernel/torture.c
@@ -573,7 +573,7 @@ static int stutter;
573 * Block until the stutter interval ends. This must be called periodically 573 * Block until the stutter interval ends. This must be called periodically
574 * by all running kthreads that need to be subject to stuttering. 574 * by all running kthreads that need to be subject to stuttering.
575 */ 575 */
576void stutter_wait(const char *title) 576bool stutter_wait(const char *title)
577{ 577{
578 int spt; 578 int spt;
579 579
@@ -590,6 +590,7 @@ void stutter_wait(const char *title)
590 } 590 }
591 torture_shutdown_absorb(title); 591 torture_shutdown_absorb(title);
592 } 592 }
593 return !!spt;
593} 594}
594EXPORT_SYMBOL_GPL(stutter_wait); 595EXPORT_SYMBOL_GPL(stutter_wait);
595 596