2020-06-18 20:45:34

by Joel Fernandes

[permalink] [raw]
Subject: [PATCH 6/7] rcutorture: Add support to get the number of wakeups of main GP kthread

This is useful to check for any improvements or degradation related to
number of GP kthread wakeups during testing.

Signed-off-by: Joel Fernandes (Google) <[email protected]>
---
kernel/rcu/Kconfig.debug | 1 +
kernel/rcu/rcu.h | 2 ++
kernel/rcu/rcutorture.c | 23 ++++++++++++++++++++++-
kernel/rcu/tree.c | 7 +++++++
4 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/kernel/rcu/Kconfig.debug b/kernel/rcu/Kconfig.debug
index 3cf6132a4bb9f..3323e3378af5a 100644
--- a/kernel/rcu/Kconfig.debug
+++ b/kernel/rcu/Kconfig.debug
@@ -50,6 +50,7 @@ config RCU_TORTURE_TEST
select TASKS_RCU
select TASKS_RUDE_RCU
select TASKS_TRACE_RCU
+ select SCHEDSTATS
default n
help
This option provides a kernel module that runs torture tests
diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
index cf66a3ccd7573..7e867e81d9738 100644
--- a/kernel/rcu/rcu.h
+++ b/kernel/rcu/rcu.h
@@ -511,6 +511,7 @@ srcu_batches_completed(struct srcu_struct *sp) { return 0; }
static inline void rcu_force_quiescent_state(void) { }
static inline void show_rcu_gp_kthreads(void) { }
static inline int rcu_get_gp_kthreads_prio(void) { return 0; }
+static inline struct task_struct *rcu_get_main_gp_kthread(void) { return 0; }
static inline void rcu_fwd_progress_check(unsigned long j) { }
#else /* #ifdef CONFIG_TINY_RCU */
bool rcu_dynticks_zero_in_eqs(int cpu, int *vp);
@@ -519,6 +520,7 @@ unsigned long rcu_exp_batches_completed(void);
unsigned long srcu_batches_completed(struct srcu_struct *sp);
void show_rcu_gp_kthreads(void);
int rcu_get_gp_kthreads_prio(void);
+struct task_struct *rcu_get_main_gp_kthread(void);
void rcu_fwd_progress_check(unsigned long j);
void rcu_force_quiescent_state(void);
extern struct workqueue_struct *rcu_gp_wq;
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index d0d265304d147..959a1f84d6904 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -23,6 +23,7 @@
#include <linux/rcupdate_wait.h>
#include <linux/interrupt.h>
#include <linux/sched/signal.h>
+#include <linux/sched/stat.h>
#include <uapi/linux/sched/types.h>
#include <linux/atomic.h>
#include <linux/bitops.h>
@@ -460,9 +461,29 @@ static void rcu_sync_torture_init(void)
INIT_LIST_HEAD(&rcu_torture_removed);
}

+unsigned long rcu_gp_nr_wakeups;
+
+static void rcu_flavor_init(void)
+{
+ rcu_sync_torture_init();
+
+ /* Make sure schedstat is enabled for GP thread wakeup count. */
+ force_schedstat_enabled();
+ rcu_gp_nr_wakeups = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
+}
+
+static void rcu_flavor_cleanup(void)
+{
+ unsigned long now_nr = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
+
+ pr_alert("End-test: Cleanup: Total GP-kthread wakeups: %lu\n",
+ now_nr - rcu_gp_nr_wakeups);
+}
+
static struct rcu_torture_ops rcu_ops = {
.ttype = RCU_FLAVOR,
- .init = rcu_sync_torture_init,
+ .init = rcu_flavor_init,
+ .cleanup = rcu_flavor_cleanup,
.readlock = rcu_torture_read_lock,
.read_delay = rcu_read_delay,
.readunlock = rcu_torture_read_unlock,
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index c3bae7a83d792..a3a175feb310a 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -175,6 +175,13 @@ int rcu_get_gp_kthreads_prio(void)
}
EXPORT_SYMBOL_GPL(rcu_get_gp_kthreads_prio);

+/* Retrieve RCU's main GP kthread task_struct */
+struct task_struct *rcu_get_main_gp_kthread(void)
+{
+ return rcu_state.gp_kthread;
+}
+EXPORT_SYMBOL_GPL(rcu_get_main_gp_kthread);
+
/*
* Number of grace periods between delays, normalized by the duration of
* the delay. The longer the delay, the more the grace periods between
--
2.27.0.111.gc72c7da667-goog


2020-06-18 23:12:53

by Paul E. McKenney

[permalink] [raw]
Subject: Re: [PATCH 6/7] rcutorture: Add support to get the number of wakeups of main GP kthread

On Thu, Jun 18, 2020 at 04:29:54PM -0400, Joel Fernandes (Google) wrote:
> This is useful to check for any improvements or degradation related to
> number of GP kthread wakeups during testing.
>
> Signed-off-by: Joel Fernandes (Google) <[email protected]>

This was a good way to collect the data for your testing, but
we can expect rcutorture to only do so much. ;-)

Thanx, Paul

> ---
> kernel/rcu/Kconfig.debug | 1 +
> kernel/rcu/rcu.h | 2 ++
> kernel/rcu/rcutorture.c | 23 ++++++++++++++++++++++-
> kernel/rcu/tree.c | 7 +++++++
> 4 files changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/rcu/Kconfig.debug b/kernel/rcu/Kconfig.debug
> index 3cf6132a4bb9f..3323e3378af5a 100644
> --- a/kernel/rcu/Kconfig.debug
> +++ b/kernel/rcu/Kconfig.debug
> @@ -50,6 +50,7 @@ config RCU_TORTURE_TEST
> select TASKS_RCU
> select TASKS_RUDE_RCU
> select TASKS_TRACE_RCU
> + select SCHEDSTATS
> default n
> help
> This option provides a kernel module that runs torture tests
> diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
> index cf66a3ccd7573..7e867e81d9738 100644
> --- a/kernel/rcu/rcu.h
> +++ b/kernel/rcu/rcu.h
> @@ -511,6 +511,7 @@ srcu_batches_completed(struct srcu_struct *sp) { return 0; }
> static inline void rcu_force_quiescent_state(void) { }
> static inline void show_rcu_gp_kthreads(void) { }
> static inline int rcu_get_gp_kthreads_prio(void) { return 0; }
> +static inline struct task_struct *rcu_get_main_gp_kthread(void) { return 0; }
> static inline void rcu_fwd_progress_check(unsigned long j) { }
> #else /* #ifdef CONFIG_TINY_RCU */
> bool rcu_dynticks_zero_in_eqs(int cpu, int *vp);
> @@ -519,6 +520,7 @@ unsigned long rcu_exp_batches_completed(void);
> unsigned long srcu_batches_completed(struct srcu_struct *sp);
> void show_rcu_gp_kthreads(void);
> int rcu_get_gp_kthreads_prio(void);
> +struct task_struct *rcu_get_main_gp_kthread(void);
> void rcu_fwd_progress_check(unsigned long j);
> void rcu_force_quiescent_state(void);
> extern struct workqueue_struct *rcu_gp_wq;
> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> index d0d265304d147..959a1f84d6904 100644
> --- a/kernel/rcu/rcutorture.c
> +++ b/kernel/rcu/rcutorture.c
> @@ -23,6 +23,7 @@
> #include <linux/rcupdate_wait.h>
> #include <linux/interrupt.h>
> #include <linux/sched/signal.h>
> +#include <linux/sched/stat.h>
> #include <uapi/linux/sched/types.h>
> #include <linux/atomic.h>
> #include <linux/bitops.h>
> @@ -460,9 +461,29 @@ static void rcu_sync_torture_init(void)
> INIT_LIST_HEAD(&rcu_torture_removed);
> }
>
> +unsigned long rcu_gp_nr_wakeups;
> +
> +static void rcu_flavor_init(void)
> +{
> + rcu_sync_torture_init();
> +
> + /* Make sure schedstat is enabled for GP thread wakeup count. */
> + force_schedstat_enabled();
> + rcu_gp_nr_wakeups = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
> +}
> +
> +static void rcu_flavor_cleanup(void)
> +{
> + unsigned long now_nr = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
> +
> + pr_alert("End-test: Cleanup: Total GP-kthread wakeups: %lu\n",
> + now_nr - rcu_gp_nr_wakeups);
> +}
> +
> static struct rcu_torture_ops rcu_ops = {
> .ttype = RCU_FLAVOR,
> - .init = rcu_sync_torture_init,
> + .init = rcu_flavor_init,
> + .cleanup = rcu_flavor_cleanup,
> .readlock = rcu_torture_read_lock,
> .read_delay = rcu_read_delay,
> .readunlock = rcu_torture_read_unlock,
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index c3bae7a83d792..a3a175feb310a 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -175,6 +175,13 @@ int rcu_get_gp_kthreads_prio(void)
> }
> EXPORT_SYMBOL_GPL(rcu_get_gp_kthreads_prio);
>
> +/* Retrieve RCU's main GP kthread task_struct */
> +struct task_struct *rcu_get_main_gp_kthread(void)
> +{
> + return rcu_state.gp_kthread;
> +}
> +EXPORT_SYMBOL_GPL(rcu_get_main_gp_kthread);
> +
> /*
> * Number of grace periods between delays, normalized by the duration of
> * the delay. The longer the delay, the more the grace periods between
> --
> 2.27.0.111.gc72c7da667-goog
>

2020-06-19 00:04:40

by Joel Fernandes

[permalink] [raw]
Subject: Re: [PATCH 6/7] rcutorture: Add support to get the number of wakeups of main GP kthread

On Thu, Jun 18, 2020 at 03:40:58PM -0700, Paul E. McKenney wrote:
> On Thu, Jun 18, 2020 at 04:29:54PM -0400, Joel Fernandes (Google) wrote:
> > This is useful to check for any improvements or degradation related to
> > number of GP kthread wakeups during testing.
> >
> > Signed-off-by: Joel Fernandes (Google) <[email protected]>
>
> This was a good way to collect the data for your testing, but
> we can expect rcutorture to only do so much. ;-)

np, I will push this one into a git tag for the next time I need it ;)

thanks,

- Joel


> Thanx, Paul
>
> > ---
> > kernel/rcu/Kconfig.debug | 1 +
> > kernel/rcu/rcu.h | 2 ++
> > kernel/rcu/rcutorture.c | 23 ++++++++++++++++++++++-
> > kernel/rcu/tree.c | 7 +++++++
> > 4 files changed, 32 insertions(+), 1 deletion(-)
> >
> > diff --git a/kernel/rcu/Kconfig.debug b/kernel/rcu/Kconfig.debug
> > index 3cf6132a4bb9f..3323e3378af5a 100644
> > --- a/kernel/rcu/Kconfig.debug
> > +++ b/kernel/rcu/Kconfig.debug
> > @@ -50,6 +50,7 @@ config RCU_TORTURE_TEST
> > select TASKS_RCU
> > select TASKS_RUDE_RCU
> > select TASKS_TRACE_RCU
> > + select SCHEDSTATS
> > default n
> > help
> > This option provides a kernel module that runs torture tests
> > diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
> > index cf66a3ccd7573..7e867e81d9738 100644
> > --- a/kernel/rcu/rcu.h
> > +++ b/kernel/rcu/rcu.h
> > @@ -511,6 +511,7 @@ srcu_batches_completed(struct srcu_struct *sp) { return 0; }
> > static inline void rcu_force_quiescent_state(void) { }
> > static inline void show_rcu_gp_kthreads(void) { }
> > static inline int rcu_get_gp_kthreads_prio(void) { return 0; }
> > +static inline struct task_struct *rcu_get_main_gp_kthread(void) { return 0; }
> > static inline void rcu_fwd_progress_check(unsigned long j) { }
> > #else /* #ifdef CONFIG_TINY_RCU */
> > bool rcu_dynticks_zero_in_eqs(int cpu, int *vp);
> > @@ -519,6 +520,7 @@ unsigned long rcu_exp_batches_completed(void);
> > unsigned long srcu_batches_completed(struct srcu_struct *sp);
> > void show_rcu_gp_kthreads(void);
> > int rcu_get_gp_kthreads_prio(void);
> > +struct task_struct *rcu_get_main_gp_kthread(void);
> > void rcu_fwd_progress_check(unsigned long j);
> > void rcu_force_quiescent_state(void);
> > extern struct workqueue_struct *rcu_gp_wq;
> > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> > index d0d265304d147..959a1f84d6904 100644
> > --- a/kernel/rcu/rcutorture.c
> > +++ b/kernel/rcu/rcutorture.c
> > @@ -23,6 +23,7 @@
> > #include <linux/rcupdate_wait.h>
> > #include <linux/interrupt.h>
> > #include <linux/sched/signal.h>
> > +#include <linux/sched/stat.h>
> > #include <uapi/linux/sched/types.h>
> > #include <linux/atomic.h>
> > #include <linux/bitops.h>
> > @@ -460,9 +461,29 @@ static void rcu_sync_torture_init(void)
> > INIT_LIST_HEAD(&rcu_torture_removed);
> > }
> >
> > +unsigned long rcu_gp_nr_wakeups;
> > +
> > +static void rcu_flavor_init(void)
> > +{
> > + rcu_sync_torture_init();
> > +
> > + /* Make sure schedstat is enabled for GP thread wakeup count. */
> > + force_schedstat_enabled();
> > + rcu_gp_nr_wakeups = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
> > +}
> > +
> > +static void rcu_flavor_cleanup(void)
> > +{
> > + unsigned long now_nr = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
> > +
> > + pr_alert("End-test: Cleanup: Total GP-kthread wakeups: %lu\n",
> > + now_nr - rcu_gp_nr_wakeups);
> > +}
> > +
> > static struct rcu_torture_ops rcu_ops = {
> > .ttype = RCU_FLAVOR,
> > - .init = rcu_sync_torture_init,
> > + .init = rcu_flavor_init,
> > + .cleanup = rcu_flavor_cleanup,
> > .readlock = rcu_torture_read_lock,
> > .read_delay = rcu_read_delay,
> > .readunlock = rcu_torture_read_unlock,
> > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> > index c3bae7a83d792..a3a175feb310a 100644
> > --- a/kernel/rcu/tree.c
> > +++ b/kernel/rcu/tree.c
> > @@ -175,6 +175,13 @@ int rcu_get_gp_kthreads_prio(void)
> > }
> > EXPORT_SYMBOL_GPL(rcu_get_gp_kthreads_prio);
> >
> > +/* Retrieve RCU's main GP kthread task_struct */
> > +struct task_struct *rcu_get_main_gp_kthread(void)
> > +{
> > + return rcu_state.gp_kthread;
> > +}
> > +EXPORT_SYMBOL_GPL(rcu_get_main_gp_kthread);
> > +
> > /*
> > * Number of grace periods between delays, normalized by the duration of
> > * the delay. The longer the delay, the more the grace periods between
> > --
> > 2.27.0.111.gc72c7da667-goog
> >

2020-06-19 02:53:14

by Paul E. McKenney

[permalink] [raw]
Subject: Re: [PATCH 6/7] rcutorture: Add support to get the number of wakeups of main GP kthread

On Thu, Jun 18, 2020 at 08:01:56PM -0400, Joel Fernandes wrote:
> On Thu, Jun 18, 2020 at 03:40:58PM -0700, Paul E. McKenney wrote:
> > On Thu, Jun 18, 2020 at 04:29:54PM -0400, Joel Fernandes (Google) wrote:
> > > This is useful to check for any improvements or degradation related to
> > > number of GP kthread wakeups during testing.
> > >
> > > Signed-off-by: Joel Fernandes (Google) <[email protected]>
> >
> > This was a good way to collect the data for your testing, but
> > we can expect rcutorture to only do so much. ;-)
>
> np, I will push this one into a git tag for the next time I need it ;)

Sounds like a plan!

Thanx, Paul

> thanks,
>
> - Joel
>
>
> > Thanx, Paul
> >
> > > ---
> > > kernel/rcu/Kconfig.debug | 1 +
> > > kernel/rcu/rcu.h | 2 ++
> > > kernel/rcu/rcutorture.c | 23 ++++++++++++++++++++++-
> > > kernel/rcu/tree.c | 7 +++++++
> > > 4 files changed, 32 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/kernel/rcu/Kconfig.debug b/kernel/rcu/Kconfig.debug
> > > index 3cf6132a4bb9f..3323e3378af5a 100644
> > > --- a/kernel/rcu/Kconfig.debug
> > > +++ b/kernel/rcu/Kconfig.debug
> > > @@ -50,6 +50,7 @@ config RCU_TORTURE_TEST
> > > select TASKS_RCU
> > > select TASKS_RUDE_RCU
> > > select TASKS_TRACE_RCU
> > > + select SCHEDSTATS
> > > default n
> > > help
> > > This option provides a kernel module that runs torture tests
> > > diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
> > > index cf66a3ccd7573..7e867e81d9738 100644
> > > --- a/kernel/rcu/rcu.h
> > > +++ b/kernel/rcu/rcu.h
> > > @@ -511,6 +511,7 @@ srcu_batches_completed(struct srcu_struct *sp) { return 0; }
> > > static inline void rcu_force_quiescent_state(void) { }
> > > static inline void show_rcu_gp_kthreads(void) { }
> > > static inline int rcu_get_gp_kthreads_prio(void) { return 0; }
> > > +static inline struct task_struct *rcu_get_main_gp_kthread(void) { return 0; }
> > > static inline void rcu_fwd_progress_check(unsigned long j) { }
> > > #else /* #ifdef CONFIG_TINY_RCU */
> > > bool rcu_dynticks_zero_in_eqs(int cpu, int *vp);
> > > @@ -519,6 +520,7 @@ unsigned long rcu_exp_batches_completed(void);
> > > unsigned long srcu_batches_completed(struct srcu_struct *sp);
> > > void show_rcu_gp_kthreads(void);
> > > int rcu_get_gp_kthreads_prio(void);
> > > +struct task_struct *rcu_get_main_gp_kthread(void);
> > > void rcu_fwd_progress_check(unsigned long j);
> > > void rcu_force_quiescent_state(void);
> > > extern struct workqueue_struct *rcu_gp_wq;
> > > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> > > index d0d265304d147..959a1f84d6904 100644
> > > --- a/kernel/rcu/rcutorture.c
> > > +++ b/kernel/rcu/rcutorture.c
> > > @@ -23,6 +23,7 @@
> > > #include <linux/rcupdate_wait.h>
> > > #include <linux/interrupt.h>
> > > #include <linux/sched/signal.h>
> > > +#include <linux/sched/stat.h>
> > > #include <uapi/linux/sched/types.h>
> > > #include <linux/atomic.h>
> > > #include <linux/bitops.h>
> > > @@ -460,9 +461,29 @@ static void rcu_sync_torture_init(void)
> > > INIT_LIST_HEAD(&rcu_torture_removed);
> > > }
> > >
> > > +unsigned long rcu_gp_nr_wakeups;
> > > +
> > > +static void rcu_flavor_init(void)
> > > +{
> > > + rcu_sync_torture_init();
> > > +
> > > + /* Make sure schedstat is enabled for GP thread wakeup count. */
> > > + force_schedstat_enabled();
> > > + rcu_gp_nr_wakeups = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
> > > +}
> > > +
> > > +static void rcu_flavor_cleanup(void)
> > > +{
> > > + unsigned long now_nr = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
> > > +
> > > + pr_alert("End-test: Cleanup: Total GP-kthread wakeups: %lu\n",
> > > + now_nr - rcu_gp_nr_wakeups);
> > > +}
> > > +
> > > static struct rcu_torture_ops rcu_ops = {
> > > .ttype = RCU_FLAVOR,
> > > - .init = rcu_sync_torture_init,
> > > + .init = rcu_flavor_init,
> > > + .cleanup = rcu_flavor_cleanup,
> > > .readlock = rcu_torture_read_lock,
> > > .read_delay = rcu_read_delay,
> > > .readunlock = rcu_torture_read_unlock,
> > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> > > index c3bae7a83d792..a3a175feb310a 100644
> > > --- a/kernel/rcu/tree.c
> > > +++ b/kernel/rcu/tree.c
> > > @@ -175,6 +175,13 @@ int rcu_get_gp_kthreads_prio(void)
> > > }
> > > EXPORT_SYMBOL_GPL(rcu_get_gp_kthreads_prio);
> > >
> > > +/* Retrieve RCU's main GP kthread task_struct */
> > > +struct task_struct *rcu_get_main_gp_kthread(void)
> > > +{
> > > + return rcu_state.gp_kthread;
> > > +}
> > > +EXPORT_SYMBOL_GPL(rcu_get_main_gp_kthread);
> > > +
> > > /*
> > > * Number of grace periods between delays, normalized by the duration of
> > > * the delay. The longer the delay, the more the grace periods between
> > > --
> > > 2.27.0.111.gc72c7da667-goog
> > >

2020-06-19 03:05:12

by Joel Fernandes

[permalink] [raw]
Subject: Re: [PATCH 6/7] rcutorture: Add support to get the number of wakeups of main GP kthread

On Thu, Jun 18, 2020 at 05:12:44PM -0700, Paul E. McKenney wrote:
> On Thu, Jun 18, 2020 at 08:01:56PM -0400, Joel Fernandes wrote:
> > On Thu, Jun 18, 2020 at 03:40:58PM -0700, Paul E. McKenney wrote:
> > > On Thu, Jun 18, 2020 at 04:29:54PM -0400, Joel Fernandes (Google) wrote:
> > > > This is useful to check for any improvements or degradation related to
> > > > number of GP kthread wakeups during testing.
> > > >
> > > > Signed-off-by: Joel Fernandes (Google) <[email protected]>
> > >
> > > This was a good way to collect the data for your testing, but
> > > we can expect rcutorture to only do so much. ;-)
> >
> > np, I will push this one into a git tag for the next time I need it ;)
>
> Sounds like a plan!

In case it is at all an option, I could put this as a statistic under
rcu_torture_stats_print(), that way it all is on the same line. But I take it
you are not too thrilled to have it for now.

thanks,

- Joel



> Thanx, Paul
>
> > thanks,
> >
> > - Joel
> >
> >
> > > Thanx, Paul
> > >
> > > > ---
> > > > kernel/rcu/Kconfig.debug | 1 +
> > > > kernel/rcu/rcu.h | 2 ++
> > > > kernel/rcu/rcutorture.c | 23 ++++++++++++++++++++++-
> > > > kernel/rcu/tree.c | 7 +++++++
> > > > 4 files changed, 32 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/kernel/rcu/Kconfig.debug b/kernel/rcu/Kconfig.debug
> > > > index 3cf6132a4bb9f..3323e3378af5a 100644
> > > > --- a/kernel/rcu/Kconfig.debug
> > > > +++ b/kernel/rcu/Kconfig.debug
> > > > @@ -50,6 +50,7 @@ config RCU_TORTURE_TEST
> > > > select TASKS_RCU
> > > > select TASKS_RUDE_RCU
> > > > select TASKS_TRACE_RCU
> > > > + select SCHEDSTATS
> > > > default n
> > > > help
> > > > This option provides a kernel module that runs torture tests
> > > > diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
> > > > index cf66a3ccd7573..7e867e81d9738 100644
> > > > --- a/kernel/rcu/rcu.h
> > > > +++ b/kernel/rcu/rcu.h
> > > > @@ -511,6 +511,7 @@ srcu_batches_completed(struct srcu_struct *sp) { return 0; }
> > > > static inline void rcu_force_quiescent_state(void) { }
> > > > static inline void show_rcu_gp_kthreads(void) { }
> > > > static inline int rcu_get_gp_kthreads_prio(void) { return 0; }
> > > > +static inline struct task_struct *rcu_get_main_gp_kthread(void) { return 0; }
> > > > static inline void rcu_fwd_progress_check(unsigned long j) { }
> > > > #else /* #ifdef CONFIG_TINY_RCU */
> > > > bool rcu_dynticks_zero_in_eqs(int cpu, int *vp);
> > > > @@ -519,6 +520,7 @@ unsigned long rcu_exp_batches_completed(void);
> > > > unsigned long srcu_batches_completed(struct srcu_struct *sp);
> > > > void show_rcu_gp_kthreads(void);
> > > > int rcu_get_gp_kthreads_prio(void);
> > > > +struct task_struct *rcu_get_main_gp_kthread(void);
> > > > void rcu_fwd_progress_check(unsigned long j);
> > > > void rcu_force_quiescent_state(void);
> > > > extern struct workqueue_struct *rcu_gp_wq;
> > > > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> > > > index d0d265304d147..959a1f84d6904 100644
> > > > --- a/kernel/rcu/rcutorture.c
> > > > +++ b/kernel/rcu/rcutorture.c
> > > > @@ -23,6 +23,7 @@
> > > > #include <linux/rcupdate_wait.h>
> > > > #include <linux/interrupt.h>
> > > > #include <linux/sched/signal.h>
> > > > +#include <linux/sched/stat.h>
> > > > #include <uapi/linux/sched/types.h>
> > > > #include <linux/atomic.h>
> > > > #include <linux/bitops.h>
> > > > @@ -460,9 +461,29 @@ static void rcu_sync_torture_init(void)
> > > > INIT_LIST_HEAD(&rcu_torture_removed);
> > > > }
> > > >
> > > > +unsigned long rcu_gp_nr_wakeups;
> > > > +
> > > > +static void rcu_flavor_init(void)
> > > > +{
> > > > + rcu_sync_torture_init();
> > > > +
> > > > + /* Make sure schedstat is enabled for GP thread wakeup count. */
> > > > + force_schedstat_enabled();
> > > > + rcu_gp_nr_wakeups = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
> > > > +}
> > > > +
> > > > +static void rcu_flavor_cleanup(void)
> > > > +{
> > > > + unsigned long now_nr = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
> > > > +
> > > > + pr_alert("End-test: Cleanup: Total GP-kthread wakeups: %lu\n",
> > > > + now_nr - rcu_gp_nr_wakeups);
> > > > +}
> > > > +
> > > > static struct rcu_torture_ops rcu_ops = {
> > > > .ttype = RCU_FLAVOR,
> > > > - .init = rcu_sync_torture_init,
> > > > + .init = rcu_flavor_init,
> > > > + .cleanup = rcu_flavor_cleanup,
> > > > .readlock = rcu_torture_read_lock,
> > > > .read_delay = rcu_read_delay,
> > > > .readunlock = rcu_torture_read_unlock,
> > > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> > > > index c3bae7a83d792..a3a175feb310a 100644
> > > > --- a/kernel/rcu/tree.c
> > > > +++ b/kernel/rcu/tree.c
> > > > @@ -175,6 +175,13 @@ int rcu_get_gp_kthreads_prio(void)
> > > > }
> > > > EXPORT_SYMBOL_GPL(rcu_get_gp_kthreads_prio);
> > > >
> > > > +/* Retrieve RCU's main GP kthread task_struct */
> > > > +struct task_struct *rcu_get_main_gp_kthread(void)
> > > > +{
> > > > + return rcu_state.gp_kthread;
> > > > +}
> > > > +EXPORT_SYMBOL_GPL(rcu_get_main_gp_kthread);
> > > > +
> > > > /*
> > > > * Number of grace periods between delays, normalized by the duration of
> > > > * the delay. The longer the delay, the more the grace periods between
> > > > --
> > > > 2.27.0.111.gc72c7da667-goog
> > > >

2020-06-19 03:38:47

by Paul E. McKenney

[permalink] [raw]
Subject: Re: [PATCH 6/7] rcutorture: Add support to get the number of wakeups of main GP kthread

On Thu, Jun 18, 2020 at 09:00:12PM -0400, Joel Fernandes wrote:
> On Thu, Jun 18, 2020 at 05:12:44PM -0700, Paul E. McKenney wrote:
> > On Thu, Jun 18, 2020 at 08:01:56PM -0400, Joel Fernandes wrote:
> > > On Thu, Jun 18, 2020 at 03:40:58PM -0700, Paul E. McKenney wrote:
> > > > On Thu, Jun 18, 2020 at 04:29:54PM -0400, Joel Fernandes (Google) wrote:
> > > > > This is useful to check for any improvements or degradation related to
> > > > > number of GP kthread wakeups during testing.
> > > > >
> > > > > Signed-off-by: Joel Fernandes (Google) <[email protected]>
> > > >
> > > > This was a good way to collect the data for your testing, but
> > > > we can expect rcutorture to only do so much. ;-)
> > >
> > > np, I will push this one into a git tag for the next time I need it ;)
> >
> > Sounds like a plan!
>
> In case it is at all an option, I could put this as a statistic under
> rcu_torture_stats_print(), that way it all is on the same line. But I take it
> you are not too thrilled to have it for now.

The thing is that rcutorture is a stress test, not a performance or
energy-efficiency test. So rcutorture will continue to wake things
up just to brutalize RCU, which makes such a statistic less helpful.

It might be something for rcuperf/rcuscale, although it is not clear that
a pure performance/scalability test would give a useful read on wakeups.
I would expect better results from a more random real-world workload.

But I bet that people already have this sort of thing set up. For
example, doesn't kbuild test robot track this sort of thing?

Thanx, Paul

> thanks,
>
> - Joel
>
>
>
> > Thanx, Paul
> >
> > > thanks,
> > >
> > > - Joel
> > >
> > >
> > > > Thanx, Paul
> > > >
> > > > > ---
> > > > > kernel/rcu/Kconfig.debug | 1 +
> > > > > kernel/rcu/rcu.h | 2 ++
> > > > > kernel/rcu/rcutorture.c | 23 ++++++++++++++++++++++-
> > > > > kernel/rcu/tree.c | 7 +++++++
> > > > > 4 files changed, 32 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/kernel/rcu/Kconfig.debug b/kernel/rcu/Kconfig.debug
> > > > > index 3cf6132a4bb9f..3323e3378af5a 100644
> > > > > --- a/kernel/rcu/Kconfig.debug
> > > > > +++ b/kernel/rcu/Kconfig.debug
> > > > > @@ -50,6 +50,7 @@ config RCU_TORTURE_TEST
> > > > > select TASKS_RCU
> > > > > select TASKS_RUDE_RCU
> > > > > select TASKS_TRACE_RCU
> > > > > + select SCHEDSTATS
> > > > > default n
> > > > > help
> > > > > This option provides a kernel module that runs torture tests
> > > > > diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
> > > > > index cf66a3ccd7573..7e867e81d9738 100644
> > > > > --- a/kernel/rcu/rcu.h
> > > > > +++ b/kernel/rcu/rcu.h
> > > > > @@ -511,6 +511,7 @@ srcu_batches_completed(struct srcu_struct *sp) { return 0; }
> > > > > static inline void rcu_force_quiescent_state(void) { }
> > > > > static inline void show_rcu_gp_kthreads(void) { }
> > > > > static inline int rcu_get_gp_kthreads_prio(void) { return 0; }
> > > > > +static inline struct task_struct *rcu_get_main_gp_kthread(void) { return 0; }
> > > > > static inline void rcu_fwd_progress_check(unsigned long j) { }
> > > > > #else /* #ifdef CONFIG_TINY_RCU */
> > > > > bool rcu_dynticks_zero_in_eqs(int cpu, int *vp);
> > > > > @@ -519,6 +520,7 @@ unsigned long rcu_exp_batches_completed(void);
> > > > > unsigned long srcu_batches_completed(struct srcu_struct *sp);
> > > > > void show_rcu_gp_kthreads(void);
> > > > > int rcu_get_gp_kthreads_prio(void);
> > > > > +struct task_struct *rcu_get_main_gp_kthread(void);
> > > > > void rcu_fwd_progress_check(unsigned long j);
> > > > > void rcu_force_quiescent_state(void);
> > > > > extern struct workqueue_struct *rcu_gp_wq;
> > > > > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> > > > > index d0d265304d147..959a1f84d6904 100644
> > > > > --- a/kernel/rcu/rcutorture.c
> > > > > +++ b/kernel/rcu/rcutorture.c
> > > > > @@ -23,6 +23,7 @@
> > > > > #include <linux/rcupdate_wait.h>
> > > > > #include <linux/interrupt.h>
> > > > > #include <linux/sched/signal.h>
> > > > > +#include <linux/sched/stat.h>
> > > > > #include <uapi/linux/sched/types.h>
> > > > > #include <linux/atomic.h>
> > > > > #include <linux/bitops.h>
> > > > > @@ -460,9 +461,29 @@ static void rcu_sync_torture_init(void)
> > > > > INIT_LIST_HEAD(&rcu_torture_removed);
> > > > > }
> > > > >
> > > > > +unsigned long rcu_gp_nr_wakeups;
> > > > > +
> > > > > +static void rcu_flavor_init(void)
> > > > > +{
> > > > > + rcu_sync_torture_init();
> > > > > +
> > > > > + /* Make sure schedstat is enabled for GP thread wakeup count. */
> > > > > + force_schedstat_enabled();
> > > > > + rcu_gp_nr_wakeups = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
> > > > > +}
> > > > > +
> > > > > +static void rcu_flavor_cleanup(void)
> > > > > +{
> > > > > + unsigned long now_nr = rcu_get_main_gp_kthread()->se.statistics.nr_wakeups;
> > > > > +
> > > > > + pr_alert("End-test: Cleanup: Total GP-kthread wakeups: %lu\n",
> > > > > + now_nr - rcu_gp_nr_wakeups);
> > > > > +}
> > > > > +
> > > > > static struct rcu_torture_ops rcu_ops = {
> > > > > .ttype = RCU_FLAVOR,
> > > > > - .init = rcu_sync_torture_init,
> > > > > + .init = rcu_flavor_init,
> > > > > + .cleanup = rcu_flavor_cleanup,
> > > > > .readlock = rcu_torture_read_lock,
> > > > > .read_delay = rcu_read_delay,
> > > > > .readunlock = rcu_torture_read_unlock,
> > > > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> > > > > index c3bae7a83d792..a3a175feb310a 100644
> > > > > --- a/kernel/rcu/tree.c
> > > > > +++ b/kernel/rcu/tree.c
> > > > > @@ -175,6 +175,13 @@ int rcu_get_gp_kthreads_prio(void)
> > > > > }
> > > > > EXPORT_SYMBOL_GPL(rcu_get_gp_kthreads_prio);
> > > > >
> > > > > +/* Retrieve RCU's main GP kthread task_struct */
> > > > > +struct task_struct *rcu_get_main_gp_kthread(void)
> > > > > +{
> > > > > + return rcu_state.gp_kthread;
> > > > > +}
> > > > > +EXPORT_SYMBOL_GPL(rcu_get_main_gp_kthread);
> > > > > +
> > > > > /*
> > > > > * Number of grace periods between delays, normalized by the duration of
> > > > > * the delay. The longer the delay, the more the grace periods between
> > > > > --
> > > > > 2.27.0.111.gc72c7da667-goog
> > > > >