rcu: Add rcu_expedite_gp() and rcu_unexpedite_gp() to rcutorture
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Thu, 19 Feb 2015 00:31:29 +0000 (16:31 -0800)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Thu, 26 Feb 2015 20:03:00 +0000 (12:03 -0800)
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
kernel/rcu/rcutorture.c

index 30d42aa55d83de9b111bd05945114641409f3596..3833aa611ae7ab74dbc88b3ff63d21e7153559cf 100644 (file)
@@ -853,6 +853,8 @@ rcu_torture_fqs(void *arg)
 static int
 rcu_torture_writer(void *arg)
 {
+       bool can_expedite = !rcu_gp_is_expedited();
+       int expediting = 0;
        unsigned long gp_snap;
        bool gp_cond1 = gp_cond, gp_exp1 = gp_exp, gp_normal1 = gp_normal;
        bool gp_sync1 = gp_sync;
@@ -865,6 +867,12 @@ rcu_torture_writer(void *arg)
        int nsynctypes = 0;
 
        VERBOSE_TOROUT_STRING("rcu_torture_writer task started");
+       pr_alert("%s" TORTURE_FLAG
+                " Grace periods expedited from boot/sysfs for %s,\n",
+                torture_type, cur_ops->name);
+       pr_alert("%s" TORTURE_FLAG
+                " Testing of dynamic grace-period expediting diabled.\n",
+                torture_type);
 
        /* Initialize synctype[] array.  If none set, take default. */
        if (!gp_cond1 && !gp_exp1 && !gp_normal1 && !gp_sync)
@@ -949,9 +957,26 @@ rcu_torture_writer(void *arg)
                        }
                }
                rcutorture_record_progress(++rcu_torture_current_version);
+               /* Cycle through nesting levels of rcu_expedite_gp() calls. */
+               if (can_expedite &&
+                   !(torture_random(&rand) & 0xff & (!!expediting - 1))) {
+                       WARN_ON_ONCE(expediting == 0 && rcu_gp_is_expedited());
+                       if (expediting >= 0)
+                               rcu_expedite_gp();
+                       else
+                               rcu_unexpedite_gp();
+                       if (++expediting > 3)
+                               expediting = -expediting;
+               }
                rcu_torture_writer_state = RTWS_STUTTER;
                stutter_wait("rcu_torture_writer");
        } while (!torture_must_stop());
+       /* Reset expediting back to unexpedited. */
+       if (expediting > 0)
+               expediting = -expediting;
+       while (can_expedite && expediting++ < 0)
+               rcu_unexpedite_gp();
+       WARN_ON_ONCE(can_expedite && rcu_gp_is_expedited());
        rcu_torture_writer_state = RTWS_STOPPING;
        torture_kthread_stopping("rcu_torture_writer");
        return 0;