aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcu/rcutorture.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-03-21 19:17:56 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-05-14 12:46:22 -0400
commitf0bf8fab4f311cffa869a462ffd182465c4caee6 (patch)
treedb29cfb047163e192e57227c86eb09e4cf42e4d0 /kernel/rcu/rcutorture.c
parenta48f3fad4f97fe6a2522fe2f5b3054b4c48a8eac (diff)
rcutorture: Explicitly test synchronous grace-period primitives
The original rcu_torture_writer() avoided testing the synchronous grace-period primitives because they were simply wrappers around call_rcu() invocations. The testing of these synchronous primitives was delegated to the fake writers. However, there really is no excuse not to test them, especially in the case of SRCU, where the wrappering is somewhat more elaborate. This commit therefore makes the default rcutorture parameters cause rcu_torture_writer() to include synchronous grace-period primitives in its testing. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'kernel/rcu/rcutorture.c')
-rw-r--r--kernel/rcu/rcutorture.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 0d27b9cc14e4..8b2748486c17 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -62,6 +62,7 @@ torture_param(bool, gp_cond, false, "Use conditional/async GP wait primitives");
62torture_param(bool, gp_exp, false, "Use expedited GP wait primitives"); 62torture_param(bool, gp_exp, false, "Use expedited GP wait primitives");
63torture_param(bool, gp_normal, false, 63torture_param(bool, gp_normal, false,
64 "Use normal (non-expedited) GP wait primitives"); 64 "Use normal (non-expedited) GP wait primitives");
65torture_param(bool, gp_sync, false, "Use synchronous GP wait primitives");
65torture_param(int, irqreader, 1, "Allow RCU readers from irq handlers"); 66torture_param(int, irqreader, 1, "Allow RCU readers from irq handlers");
66torture_param(int, n_barrier_cbs, 0, 67torture_param(int, n_barrier_cbs, 0,
67 "# of callbacks/kthreads for barrier testing"); 68 "# of callbacks/kthreads for barrier testing");
@@ -147,8 +148,9 @@ static int rcu_torture_writer_state;
147#define RTWS_EXP_SYNC 4 148#define RTWS_EXP_SYNC 4
148#define RTWS_COND_GET 5 149#define RTWS_COND_GET 5
149#define RTWS_COND_SYNC 6 150#define RTWS_COND_SYNC 6
150#define RTWS_STUTTER 7 151#define RTWS_SYNC 7
151#define RTWS_STOPPING 8 152#define RTWS_STUTTER 8
153#define RTWS_STOPPING 9
152 154
153#if defined(MODULE) || defined(CONFIG_RCU_TORTURE_TEST_RUNNABLE) 155#if defined(MODULE) || defined(CONFIG_RCU_TORTURE_TEST_RUNNABLE)
154#define RCUTORTURE_RUNNABLE_INIT 1 156#define RCUTORTURE_RUNNABLE_INIT 1
@@ -746,19 +748,21 @@ rcu_torture_writer(void *arg)
746{ 748{
747 unsigned long gp_snap; 749 unsigned long gp_snap;
748 bool gp_cond1 = gp_cond, gp_exp1 = gp_exp, gp_normal1 = gp_normal; 750 bool gp_cond1 = gp_cond, gp_exp1 = gp_exp, gp_normal1 = gp_normal;
751 bool gp_sync1 = gp_sync;
749 int i; 752 int i;
750 struct rcu_torture *rp; 753 struct rcu_torture *rp;
751 struct rcu_torture *old_rp; 754 struct rcu_torture *old_rp;
752 static DEFINE_TORTURE_RANDOM(rand); 755 static DEFINE_TORTURE_RANDOM(rand);
753 int synctype[] = { RTWS_DEF_FREE, RTWS_EXP_SYNC, RTWS_COND_GET }; 756 int synctype[] = { RTWS_DEF_FREE, RTWS_EXP_SYNC,
757 RTWS_COND_GET, RTWS_SYNC };
754 int nsynctypes = 0; 758 int nsynctypes = 0;
755 759
756 VERBOSE_TOROUT_STRING("rcu_torture_writer task started"); 760 VERBOSE_TOROUT_STRING("rcu_torture_writer task started");
757 set_user_nice(current, MAX_NICE); 761 set_user_nice(current, MAX_NICE);
758 762
759 /* Initialize synctype[] array. If none set, take default. */ 763 /* Initialize synctype[] array. If none set, take default. */
760 if (!gp_cond1 && !gp_exp1 && !gp_normal1) 764 if (!gp_cond1 && !gp_exp1 && !gp_normal1 && !gp_sync)
761 gp_cond1 = gp_exp1 = gp_normal1 = true; 765 gp_cond1 = gp_exp1 = gp_normal1 = gp_sync1 = true;
762 if (gp_cond1 && cur_ops->get_state && cur_ops->cond_sync) 766 if (gp_cond1 && cur_ops->get_state && cur_ops->cond_sync)
763 synctype[nsynctypes++] = RTWS_COND_GET; 767 synctype[nsynctypes++] = RTWS_COND_GET;
764 else if (gp_cond && (!cur_ops->get_state || !cur_ops->cond_sync)) 768 else if (gp_cond && (!cur_ops->get_state || !cur_ops->cond_sync))
@@ -771,8 +775,17 @@ rcu_torture_writer(void *arg)
771 synctype[nsynctypes++] = RTWS_DEF_FREE; 775 synctype[nsynctypes++] = RTWS_DEF_FREE;
772 else if (gp_normal && !cur_ops->deferred_free) 776 else if (gp_normal && !cur_ops->deferred_free)
773 pr_alert("rcu_torture_writer: gp_normal without primitives.\n"); 777 pr_alert("rcu_torture_writer: gp_normal without primitives.\n");
778 if (gp_sync1 && cur_ops->sync)
779 synctype[nsynctypes++] = RTWS_SYNC;
780 else if (gp_sync && !cur_ops->sync)
781 pr_alert("rcu_torture_writer: gp_sync without primitives.\n");
774 if (WARN_ONCE(nsynctypes == 0, 782 if (WARN_ONCE(nsynctypes == 0,
775 "rcu_torture_writer: No update-side primitives.\n")) { 783 "rcu_torture_writer: No update-side primitives.\n")) {
784 /*
785 * No updates primitives, so don't try updating.
786 * The resulting test won't be testing much, hence the
787 * above WARN_ONCE().
788 */
776 rcu_torture_writer_state = RTWS_STOPPING; 789 rcu_torture_writer_state = RTWS_STOPPING;
777 torture_kthread_stopping("rcu_torture_writer"); 790 torture_kthread_stopping("rcu_torture_writer");
778 } 791 }
@@ -819,6 +832,11 @@ rcu_torture_writer(void *arg)
819 cur_ops->cond_sync(gp_snap); 832 cur_ops->cond_sync(gp_snap);
820 rcu_torture_pipe_update(old_rp); 833 rcu_torture_pipe_update(old_rp);
821 break; 834 break;
835 case RTWS_SYNC:
836 rcu_torture_writer_state = RTWS_SYNC;
837 cur_ops->sync();
838 rcu_torture_pipe_update(old_rp);
839 break;
822 default: 840 default:
823 WARN_ON_ONCE(1); 841 WARN_ON_ONCE(1);
824 break; 842 break;