On Wed, Mar 13, 2019 at 01:26:40PM -0700, Tejun Heo wrote: > Hello, > > On Wed, Mar 13, 2019 at 03:40:04PM -0400, Barret Rhoden wrote: > > Are there any other alternatives? Not using static SRCU in any code > > that could be built as a module seems a little harsh. > > Yes, allocate the srcu dynamically on module init and destroy on > module exit. That's how the other similar case got solved too. We > can't keep bumping up reserved size by the number of static SRCUs in > modules. It's mostly there to make trivial small things easier. We > don't lose anything meaningful by allocating srcu dynamically.
Should I define DEFINE_SRCU() and DEFINE_STATIC_SRCU() only if !defined(MODULE)? Untested (probably doesn't even build) patch below. Thanx, Paul ------------------------------------------------------------------------ diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h index 7f7c8c050f63..a979da9cf71f 100644 --- a/include/linux/srcutree.h +++ b/include/linux/srcutree.h @@ -105,6 +105,8 @@ struct srcu_struct { * Define and initialize a srcu struct at build time. * Do -not- call init_srcu_struct() nor cleanup_srcu_struct() on it. * + * Build-time srcu_struct definition is not allowed in modules. + * * Note that although DEFINE_STATIC_SRCU() hides the name from other * files, the per-CPU variable rules nevertheless require that the * chosen name be globally unique. These rules also prohibit use of @@ -120,11 +122,13 @@ struct srcu_struct { * * See include/linux/percpu-defs.h for the rules on per-CPU variables. */ -#define __DEFINE_SRCU(name, is_static) \ - static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data);\ +#ifndef MODULE +# define __DEFINE_SRCU(name, is_static) \ + static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data); \ is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name##_srcu_data) -#define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */) -#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static) +# define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */) +# define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static) +#endif void synchronize_srcu_expedited(struct srcu_struct *ssp); void srcu_barrier(struct srcu_struct *ssp); diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 5ff797fd3715..7cf1e3aed695 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -496,9 +496,18 @@ static struct rcu_torture_ops rcu_busted_ops = { * Definitions for srcu torture testing. */ -DEFINE_STATIC_SRCU(srcu_ctl); static struct srcu_struct srcu_ctld; -static struct srcu_struct *srcu_ctlp = &srcu_ctl; +static struct srcu_struct *srcu_ctlp; + +#ifndef MODULE +DEFINE_STATIC_SRCU(srcu_ctl); + +static void srcu_torture_init(void) +{ + rcu_sync_torture_init(); + srcu_ctlp = &srcu_ctl; +} +#endif static int srcu_torture_read_lock(void) __acquires(srcu_ctlp) { @@ -565,9 +574,10 @@ static void srcu_torture_synchronize_expedited(void) synchronize_srcu_expedited(srcu_ctlp); } +#ifndef MODULE static struct rcu_torture_ops srcu_ops = { .ttype = SRCU_FLAVOR, - .init = rcu_sync_torture_init, + .init = srcu_torture_init, .readlock = srcu_torture_read_lock, .read_delay = srcu_read_delay, .readunlock = srcu_torture_read_unlock, @@ -581,25 +591,25 @@ static struct rcu_torture_ops srcu_ops = { .irq_capable = 1, .name = "srcu" }; +#endif -static void srcu_torture_init(void) +static void srcud_torture_init(void) { rcu_sync_torture_init(); WARN_ON(init_srcu_struct(&srcu_ctld)); srcu_ctlp = &srcu_ctld; } -static void srcu_torture_cleanup(void) +static void srcud_torture_cleanup(void) { cleanup_srcu_struct(&srcu_ctld); - srcu_ctlp = &srcu_ctl; /* In case of a later rcutorture run. */ } /* As above, but dynamically allocated. */ static struct rcu_torture_ops srcud_ops = { .ttype = SRCU_FLAVOR, - .init = srcu_torture_init, - .cleanup = srcu_torture_cleanup, + .init = srcud_torture_init, + .cleanup = srcud_torture_cleanup, .readlock = srcu_torture_read_lock, .read_delay = srcu_read_delay, .readunlock = srcu_torture_read_unlock, @@ -617,8 +627,8 @@ static struct rcu_torture_ops srcud_ops = { /* As above, but broken due to inappropriate reader extension. */ static struct rcu_torture_ops busted_srcud_ops = { .ttype = SRCU_FLAVOR, - .init = srcu_torture_init, - .cleanup = srcu_torture_cleanup, + .init = srcud_torture_init, + .cleanup = srcud_torture_cleanup, .readlock = srcu_torture_read_lock, .read_delay = rcu_read_delay, .readunlock = srcu_torture_read_unlock,