|
@@ -62,6 +62,7 @@ torture_param(bool, gp_cond, false, "Use conditional/async GP wait primitives");
|
|
|
torture_param(bool, gp_exp, false, "Use expedited GP wait primitives");
|
|
|
torture_param(bool, gp_normal, false,
|
|
|
"Use normal (non-expedited) GP wait primitives");
|
|
|
+torture_param(bool, gp_sync, false, "Use synchronous GP wait primitives");
|
|
|
torture_param(int, irqreader, 1, "Allow RCU readers from irq handlers");
|
|
|
torture_param(int, n_barrier_cbs, 0,
|
|
|
"# of callbacks/kthreads for barrier testing");
|
|
@@ -147,8 +148,9 @@ static int rcu_torture_writer_state;
|
|
|
#define RTWS_EXP_SYNC 4
|
|
|
#define RTWS_COND_GET 5
|
|
|
#define RTWS_COND_SYNC 6
|
|
|
-#define RTWS_STUTTER 7
|
|
|
-#define RTWS_STOPPING 8
|
|
|
+#define RTWS_SYNC 7
|
|
|
+#define RTWS_STUTTER 8
|
|
|
+#define RTWS_STOPPING 9
|
|
|
|
|
|
#if defined(MODULE) || defined(CONFIG_RCU_TORTURE_TEST_RUNNABLE)
|
|
|
#define RCUTORTURE_RUNNABLE_INIT 1
|
|
@@ -746,19 +748,21 @@ rcu_torture_writer(void *arg)
|
|
|
{
|
|
|
unsigned long gp_snap;
|
|
|
bool gp_cond1 = gp_cond, gp_exp1 = gp_exp, gp_normal1 = gp_normal;
|
|
|
+ bool gp_sync1 = gp_sync;
|
|
|
int i;
|
|
|
struct rcu_torture *rp;
|
|
|
struct rcu_torture *old_rp;
|
|
|
static DEFINE_TORTURE_RANDOM(rand);
|
|
|
- int synctype[] = { RTWS_DEF_FREE, RTWS_EXP_SYNC, RTWS_COND_GET };
|
|
|
+ int synctype[] = { RTWS_DEF_FREE, RTWS_EXP_SYNC,
|
|
|
+ RTWS_COND_GET, RTWS_SYNC };
|
|
|
int nsynctypes = 0;
|
|
|
|
|
|
VERBOSE_TOROUT_STRING("rcu_torture_writer task started");
|
|
|
set_user_nice(current, MAX_NICE);
|
|
|
|
|
|
/* Initialize synctype[] array. If none set, take default. */
|
|
|
- if (!gp_cond1 && !gp_exp1 && !gp_normal1)
|
|
|
- gp_cond1 = gp_exp1 = gp_normal1 = true;
|
|
|
+ if (!gp_cond1 && !gp_exp1 && !gp_normal1 && !gp_sync)
|
|
|
+ gp_cond1 = gp_exp1 = gp_normal1 = gp_sync1 = true;
|
|
|
if (gp_cond1 && cur_ops->get_state && cur_ops->cond_sync)
|
|
|
synctype[nsynctypes++] = RTWS_COND_GET;
|
|
|
else if (gp_cond && (!cur_ops->get_state || !cur_ops->cond_sync))
|
|
@@ -771,8 +775,17 @@ rcu_torture_writer(void *arg)
|
|
|
synctype[nsynctypes++] = RTWS_DEF_FREE;
|
|
|
else if (gp_normal && !cur_ops->deferred_free)
|
|
|
pr_alert("rcu_torture_writer: gp_normal without primitives.\n");
|
|
|
+ if (gp_sync1 && cur_ops->sync)
|
|
|
+ synctype[nsynctypes++] = RTWS_SYNC;
|
|
|
+ else if (gp_sync && !cur_ops->sync)
|
|
|
+ pr_alert("rcu_torture_writer: gp_sync without primitives.\n");
|
|
|
if (WARN_ONCE(nsynctypes == 0,
|
|
|
"rcu_torture_writer: No update-side primitives.\n")) {
|
|
|
+ /*
|
|
|
+ * No updates primitives, so don't try updating.
|
|
|
+ * The resulting test won't be testing much, hence the
|
|
|
+ * above WARN_ONCE().
|
|
|
+ */
|
|
|
rcu_torture_writer_state = RTWS_STOPPING;
|
|
|
torture_kthread_stopping("rcu_torture_writer");
|
|
|
}
|
|
@@ -819,6 +832,11 @@ rcu_torture_writer(void *arg)
|
|
|
cur_ops->cond_sync(gp_snap);
|
|
|
rcu_torture_pipe_update(old_rp);
|
|
|
break;
|
|
|
+ case RTWS_SYNC:
|
|
|
+ rcu_torture_writer_state = RTWS_SYNC;
|
|
|
+ cur_ops->sync();
|
|
|
+ rcu_torture_pipe_update(old_rp);
|
|
|
+ break;
|
|
|
default:
|
|
|
WARN_ON_ONCE(1);
|
|
|
break;
|