]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
rcutorture: Make rcutorture support print rcu-tasks gp state
authorZqiang <qiang.zhang1211@gmail.com>
Mon, 18 Mar 2024 09:34:11 +0000 (17:34 +0800)
committerUladzislau Rezki (Sony) <urezki@gmail.com>
Tue, 16 Apr 2024 09:16:35 +0000 (11:16 +0200)
This commit make rcu-tasks related rcutorture test support rcu-tasks
gp state printing when the writer stall occurs or the at the end of
rcutorture test, and generate rcu_ops->get_gp_data() operation to
simplify the acquisition of gp state for different types of rcutorture
tests.

Signed-off-by: Zqiang <qiang.zhang1211@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
kernel/rcu/rcu.h
kernel/rcu/rcutorture.c
kernel/rcu/srcutree.c
kernel/rcu/tasks.h
kernel/rcu/tree.c

index 86fce206560e83f05e3a57114e5771e0c0a76b7d..38238e595a61a45fd263df234e199c722149968b 100644 (file)
@@ -522,12 +522,18 @@ static inline void show_rcu_tasks_gp_kthreads(void) {}
 
 #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 */
@@ -557,8 +563,7 @@ static inline void rcu_set_jiffies_lazy_flush(unsigned long j) { }
 #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,
@@ -566,8 +571,7 @@ void do_trace_rcu_torture_read(const char *rcutorturename,
                               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;
@@ -587,20 +591,16 @@ static inline void rcu_gp_set_torture_wait(int duration) { }
 
 #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
index 2f43d31fb7a54cb0c4a68abc32dea0d4412bad9e..85ff8a32f75ae890620cf597d9c1ea6c2bf6bd61 100644 (file)
@@ -381,6 +381,7 @@ struct rcu_torture_ops {
        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;
@@ -569,6 +570,7 @@ static struct rcu_torture_ops rcu_ops = {
        .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,
@@ -628,6 +630,11 @@ static struct srcu_struct srcu_ctld;
 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)
@@ -736,6 +743,7 @@ static struct rcu_torture_ops srcu_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),
@@ -774,6 +782,7 @@ static struct rcu_torture_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),
@@ -882,6 +891,7 @@ static struct rcu_torture_ops tasks_ops = {
        .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,
@@ -922,6 +932,7 @@ static struct rcu_torture_ops tasks_rude_ops = {
        .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,
@@ -974,6 +985,7 @@ static struct rcu_torture_ops tasks_tracing_ops = {
        .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,
@@ -2264,10 +2276,8 @@ rcu_torture_stats_print(void)
                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(),
@@ -3390,8 +3400,8 @@ rcu_torture_cleanup(void)
                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));
@@ -3762,8 +3772,8 @@ rcu_torture_init(void)
                        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);
index e4d673fc30f42f9c1278e2c5ee07d1ee894706f3..bc4b58b0204e982e5d412b6afc0cbb91a38dc903 100644 (file)
@@ -1826,12 +1826,9 @@ static void process_srcu(struct work_struct *work)
        srcu_reschedule(ssp, curdelay);
 }
 
-void srcutorture_get_gp_data(enum rcutorture_type test_type,
-                            struct srcu_struct *ssp, int *flags,
+void srcutorture_get_gp_data(struct srcu_struct *ssp, int *flags,
                             unsigned long *gp_seq)
 {
-       if (test_type != SRCU_FLAVOR)
-               return;
        *flags = 0;
        *gp_seq = rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq);
 }
index 147b5945d67a046dd568e6df586881f8c1a0c25f..a1af7dadc0f7f60e8d7f40301a1f6c62f6f20d73 100644 (file)
@@ -1178,6 +1178,13 @@ struct task_struct *get_rcu_tasks_gp_kthread(void)
 }
 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
@@ -1358,6 +1365,13 @@ struct task_struct *get_rcu_tasks_rude_gp_kthread(void)
 }
 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 */
 
 ////////////////////////////////////////////////////////////////////////
@@ -2010,6 +2024,13 @@ struct task_struct *get_rcu_tasks_trace_gp_kthread(void)
 }
 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 */
index d9642dd06c2535d9a59682e9b9416d980bd6703c..60e79ed737003f8b8846c6260d9efa2fe4172169 100644 (file)
@@ -508,17 +508,10 @@ static struct rcu_node *rcu_get_root(void)
 /*
  * Send along grace-period-related data for rcutorture diagnostics.
  */
-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)
 {
-       switch (test_type) {
-       case RCU_FLAVOR:
-               *flags = READ_ONCE(rcu_state.gp_flags);
-               *gp_seq = rcu_seq_current(&rcu_state.gp_seq);
-               break;
-       default:
-               break;
-       }
+       *flags = READ_ONCE(rcu_state.gp_flags);
+       *gp_seq = rcu_seq_current(&rcu_state.gp_seq);
 }
 EXPORT_SYMBOL_GPL(rcutorture_get_gp_data);