From: "Paul E. McKenney" <[email protected]>

Full testing of the new SRCU polling API requires that the fake
writers also use it in order to test concurrent calls to all of the API
members, especially start_poll_synchronize_srcu().  This commit makes
rcu_torture_fakewriter() use all available blocking grace-period-wait
primitives available from the RCU flavor under test.

Link: https://lore.kernel.org/rcu/[email protected]/
Reported-by: Kent Overstreet <[email protected]>
Signed-off-by: Paul E. McKenney <[email protected]>
---
 kernel/rcu/rcutorture.c | 40 ++++++++++++++++++++++++++++++++--------
 1 file changed, 32 insertions(+), 8 deletions(-)

diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index ea44a2b..1b70aa4 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1289,6 +1289,8 @@ rcu_torture_writer(void *arg)
 static int
 rcu_torture_fakewriter(void *arg)
 {
+       unsigned long gp_snap;
+       int i;
        DEFINE_TORTURE_RANDOM(rand);
 
        VERBOSE_TOROUT_STRING("rcu_torture_fakewriter task started");
@@ -1300,15 +1302,37 @@ rcu_torture_fakewriter(void *arg)
                if (cur_ops->cb_barrier != NULL &&
                    torture_random(&rand) % (nfakewriters * 8) == 0) {
                        cur_ops->cb_barrier();
-               } else if (gp_normal == gp_exp) {
-                       if (cur_ops->sync && torture_random(&rand) & 0x80)
-                               cur_ops->sync();
-                       else if (cur_ops->exp_sync)
+               } else {
+                       switch (synctype[torture_random(&rand) % nsynctypes]) {
+                       case RTWS_DEF_FREE:
+                               break;
+                       case RTWS_EXP_SYNC:
                                cur_ops->exp_sync();
-               } else if (gp_normal && cur_ops->sync) {
-                       cur_ops->sync();
-               } else if (cur_ops->exp_sync) {
-                       cur_ops->exp_sync();
+                               break;
+                       case RTWS_COND_GET:
+                               gp_snap = cur_ops->get_gp_state();
+                               i = torture_random(&rand) % 16;
+                               if (i != 0)
+                                       schedule_timeout_interruptible(i);
+                               udelay(torture_random(&rand) % 1000);
+                               cur_ops->cond_sync(gp_snap);
+                               break;
+                       case RTWS_POLL_GET:
+                               gp_snap = cur_ops->start_gp_poll();
+                               while (!cur_ops->poll_gp_state(gp_snap)) {
+                                       i = torture_random(&rand) % 16;
+                                       if (i != 0)
+                                               
schedule_timeout_interruptible(i);
+                                       udelay(torture_random(&rand) % 1000);
+                               }
+                               break;
+                       case RTWS_SYNC:
+                               cur_ops->sync();
+                               break;
+                       default:
+                               WARN_ON_ONCE(1);
+                               break;
+                       }
                }
                stutter_wait("rcu_torture_fakewriter");
        } while (!torture_must_stop());
-- 
2.9.5

Reply via email to