#ifdef CONFIG_TASKS_RCU
 struct task_struct *get_rcu_tasks_gp_kthread(void);
+void rcu_tasks_get_gp_data(int *flags, unsigned long *gp_seq);
 #endif // # ifdef CONFIG_TASKS_RCU
 
 #ifdef CONFIG_TASKS_RUDE_RCU
 struct task_struct *get_rcu_tasks_rude_gp_kthread(void);
+void rcu_tasks_rude_get_gp_data(int *flags, unsigned long *gp_seq);
 #endif // # ifdef CONFIG_TASKS_RUDE_RCU
 
+#ifdef CONFIG_TASKS_TRACE_RCU
+void rcu_tasks_trace_get_gp_data(int *flags, unsigned long *gp_seq);
+#endif
+
 #ifdef CONFIG_TASKS_RCU_GENERIC
 void tasks_cblist_init_generic(void);
 #else /* #ifdef CONFIG_TASKS_RCU_GENERIC */
 #endif
 
 #if defined(CONFIG_TREE_RCU)
-void rcutorture_get_gp_data(enum rcutorture_type test_type, int *flags,
-                           unsigned long *gp_seq);
+void rcutorture_get_gp_data(int *flags, unsigned long *gp_seq);
 void do_trace_rcu_torture_read(const char *rcutorturename,
                               struct rcu_head *rhp,
                               unsigned long secs,
                               unsigned long c);
 void rcu_gp_set_torture_wait(int duration);
 #else
-static inline void rcutorture_get_gp_data(enum rcutorture_type test_type,
-                                         int *flags, unsigned long *gp_seq)
+static inline void rcutorture_get_gp_data(int *flags, unsigned long *gp_seq)
 {
        *flags = 0;
        *gp_seq = 0;
 
 #ifdef CONFIG_TINY_SRCU
 
-static inline void srcutorture_get_gp_data(enum rcutorture_type test_type,
-                                          struct srcu_struct *sp, int *flags,
+static inline void srcutorture_get_gp_data(struct srcu_struct *sp, int *flags,
                                           unsigned long *gp_seq)
 {
-       if (test_type != SRCU_FLAVOR)
-               return;
        *flags = 0;
        *gp_seq = sp->srcu_idx;
 }
 
 #elif defined(CONFIG_TREE_SRCU)
 
-void srcutorture_get_gp_data(enum rcutorture_type test_type,
-                            struct srcu_struct *sp, int *flags,
+void srcutorture_get_gp_data(struct srcu_struct *sp, int *flags,
                             unsigned long *gp_seq);
 
 #endif
 
        void (*gp_kthread_dbg)(void);
        bool (*check_boost_failed)(unsigned long gp_state, int *cpup);
        int (*stall_dur)(void);
+       void (*get_gp_data)(int *flags, unsigned long *gp_seq);
        long cbflood_max;
        int irq_capable;
        int can_boost;
        .gp_kthread_dbg         = show_rcu_gp_kthreads,
        .check_boost_failed     = rcu_check_boost_fail,
        .stall_dur              = rcu_jiffies_till_stall_check,
+       .get_gp_data            = rcutorture_get_gp_data,
        .irq_capable            = 1,
        .can_boost              = IS_ENABLED(CONFIG_RCU_BOOST),
        .extendables            = RCUTORTURE_MAX_EXTEND,
 static struct srcu_struct *srcu_ctlp = &srcu_ctl;
 static struct rcu_torture_ops srcud_ops;
 
+static void srcu_get_gp_data(int *flags, unsigned long *gp_seq)
+{
+       srcutorture_get_gp_data(srcu_ctlp, flags, gp_seq);
+}
+
 static int srcu_torture_read_lock(void)
 {
        if (cur_ops == &srcud_ops)
        .call           = srcu_torture_call,
        .cb_barrier     = srcu_torture_barrier,
        .stats          = srcu_torture_stats,
+       .get_gp_data    = srcu_get_gp_data,
        .cbflood_max    = 50000,
        .irq_capable    = 1,
        .no_pi_lock     = IS_ENABLED(CONFIG_TINY_SRCU),
        .call           = srcu_torture_call,
        .cb_barrier     = srcu_torture_barrier,
        .stats          = srcu_torture_stats,
+       .get_gp_data    = srcu_get_gp_data,
        .cbflood_max    = 50000,
        .irq_capable    = 1,
        .no_pi_lock     = IS_ENABLED(CONFIG_TINY_SRCU),
        .call           = call_rcu_tasks,
        .cb_barrier     = rcu_barrier_tasks,
        .gp_kthread_dbg = show_rcu_tasks_classic_gp_kthread,
+       .get_gp_data    = rcu_tasks_get_gp_data,
        .fqs            = NULL,
        .stats          = NULL,
        .irq_capable    = 1,
        .call           = call_rcu_tasks_rude,
        .cb_barrier     = rcu_barrier_tasks_rude,
        .gp_kthread_dbg = show_rcu_tasks_rude_gp_kthread,
+       .get_gp_data    = rcu_tasks_rude_get_gp_data,
        .cbflood_max    = 50000,
        .fqs            = NULL,
        .stats          = NULL,
        .call           = call_rcu_tasks_trace,
        .cb_barrier     = rcu_barrier_tasks_trace,
        .gp_kthread_dbg = show_rcu_tasks_trace_gp_kthread,
+       .get_gp_data    = rcu_tasks_trace_get_gp_data,
        .cbflood_max    = 50000,
        .fqs            = NULL,
        .stats          = NULL,
                int __maybe_unused flags = 0;
                unsigned long __maybe_unused gp_seq = 0;
 
-               rcutorture_get_gp_data(cur_ops->ttype,
-                                      &flags, &gp_seq);
-               srcutorture_get_gp_data(cur_ops->ttype, srcu_ctlp,
-                                       &flags, &gp_seq);
+               if (cur_ops->get_gp_data)
+                       cur_ops->get_gp_data(&flags, &gp_seq);
                wtp = READ_ONCE(writer_task);
                pr_alert("??? Writer stall state %s(%d) g%lu f%#x ->state %#x cpu %d\n",
                         rcu_torture_writer_state_getname(),
                fakewriter_tasks = NULL;
        }
 
-       rcutorture_get_gp_data(cur_ops->ttype, &flags, &gp_seq);
-       srcutorture_get_gp_data(cur_ops->ttype, srcu_ctlp, &flags, &gp_seq);
+       if (cur_ops->get_gp_data)
+               cur_ops->get_gp_data(&flags, &gp_seq);
        pr_alert("%s:  End-test grace-period state: g%ld f%#x total-gps=%ld\n",
                 cur_ops->name, (long)gp_seq, flags,
                 rcutorture_seq_diff(gp_seq, start_gp_seq));
                        nrealreaders = 1;
        }
        rcu_torture_print_module_parms(cur_ops, "Start of test");
-       rcutorture_get_gp_data(cur_ops->ttype, &flags, &gp_seq);
-       srcutorture_get_gp_data(cur_ops->ttype, srcu_ctlp, &flags, &gp_seq);
+       if (cur_ops->get_gp_data)
+               cur_ops->get_gp_data(&flags, &gp_seq);
        start_gp_seq = gp_seq;
        pr_alert("%s:  Start-test grace-period state: g%ld f%#x\n",
                 cur_ops->name, (long)gp_seq, flags);
 
 }
 EXPORT_SYMBOL_GPL(get_rcu_tasks_gp_kthread);
 
+void rcu_tasks_get_gp_data(int *flags, unsigned long *gp_seq)
+{
+       *flags = 0;
+       *gp_seq = rcu_seq_current(&rcu_tasks.tasks_gp_seq);
+}
+EXPORT_SYMBOL_GPL(rcu_tasks_get_gp_data);
+
 /*
  * Protect against tasklist scan blind spot while the task is exiting and
  * may be removed from the tasklist.  Do this by adding the task to yet
 }
 EXPORT_SYMBOL_GPL(get_rcu_tasks_rude_gp_kthread);
 
+void rcu_tasks_rude_get_gp_data(int *flags, unsigned long *gp_seq)
+{
+       *flags = 0;
+       *gp_seq = rcu_seq_current(&rcu_tasks_rude.tasks_gp_seq);
+}
+EXPORT_SYMBOL_GPL(rcu_tasks_rude_get_gp_data);
+
 #endif /* #ifdef CONFIG_TASKS_RUDE_RCU */
 
 ////////////////////////////////////////////////////////////////////////
 }
 EXPORT_SYMBOL_GPL(get_rcu_tasks_trace_gp_kthread);
 
+void rcu_tasks_trace_get_gp_data(int *flags, unsigned long *gp_seq)
+{
+       *flags = 0;
+       *gp_seq = rcu_seq_current(&rcu_tasks_trace.tasks_gp_seq);
+}
+EXPORT_SYMBOL_GPL(rcu_tasks_trace_get_gp_data);
+
 #else /* #ifdef CONFIG_TASKS_TRACE_RCU */
 static void exit_tasks_rcu_finish_trace(struct task_struct *t) { }
 #endif /* #else #ifdef CONFIG_TASKS_TRACE_RCU */