public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] srcu: Add DEFINE_SRCU()
@ 2012-10-12 17:14 Lai Jiangshan
  2012-10-12 17:14 ` [PATCH 1/4] srcu: add my name Lai Jiangshan
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Lai Jiangshan @ 2012-10-12 17:14 UTC (permalink / raw)
  To: linux-kernel, Paul E. McKenney; +Cc: Lai Jiangshan

These patches add a simple DEFINE_SRCU() which define and init
the srcu struct in build time, and allow us use srcu in very early
boot time.

Lai Jiangshan (4):
  srcu: add my name
  srcu: export process_srcu()
  srcu: add DEFINE_SRCU
  rcutorture: use DEFINE_STATIC_SRCU()

 include/linux/srcu.h |   34 ++++++++++++++++++++++++++++++++++
 kernel/rcutorture.c  |   41 ++++++-----------------------------------
 kernel/srcu.c        |    8 ++++----
 3 files changed, 44 insertions(+), 39 deletions(-)

-- 
1.7.7.6


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/4] srcu: add my name
  2012-10-12 17:14 [PATCH 0/4] srcu: Add DEFINE_SRCU() Lai Jiangshan
@ 2012-10-12 17:14 ` Lai Jiangshan
  2012-10-12 17:14 ` [PATCH 2/4] srcu: export process_srcu() Lai Jiangshan
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Lai Jiangshan @ 2012-10-12 17:14 UTC (permalink / raw)
  To: linux-kernel, Paul E. McKenney; +Cc: Lai Jiangshan

I changed a lot for srcu, add my name here, thus any one can blame/contact
to me when needed.

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
---
 include/linux/srcu.h |    2 ++
 kernel/srcu.c        |    2 ++
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index 55a5c52..a55ddb1 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -16,8 +16,10 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  * Copyright (C) IBM Corporation, 2006
+ * Copyright (C) Fujitsu, 2012
  *
  * Author: Paul McKenney <paulmck@us.ibm.com>
+ *	   Lai Jiangshan <laijs@cn.fujitsu.com>
  *
  * For detailed explanation of Read-Copy Update mechanism see -
  * 		Documentation/RCU/ *.txt
diff --git a/kernel/srcu.c b/kernel/srcu.c
index 2095be3..610486d 100644
--- a/kernel/srcu.c
+++ b/kernel/srcu.c
@@ -16,8 +16,10 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  * Copyright (C) IBM Corporation, 2006
+ * Copyright (C) Fujitsu, 2012
  *
  * Author: Paul McKenney <paulmck@us.ibm.com>
+ *	   Lai Jiangshan <laijs@cn.fujitsu.com>
  *
  * For detailed explanation of Read-Copy Update mechanism see -
  * 		Documentation/RCU/ *.txt
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/4] srcu: export process_srcu()
  2012-10-12 17:14 [PATCH 0/4] srcu: Add DEFINE_SRCU() Lai Jiangshan
  2012-10-12 17:14 ` [PATCH 1/4] srcu: add my name Lai Jiangshan
@ 2012-10-12 17:14 ` Lai Jiangshan
  2012-10-12 17:14 ` [PATCH 3/4] srcu: add DEFINE_SRCU() Lai Jiangshan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Lai Jiangshan @ 2012-10-12 17:14 UTC (permalink / raw)
  To: linux-kernel, Paul E. McKenney; +Cc: Lai Jiangshan

process_srcu() will be used in DEFINE_SRCU() (only).
Although it is exported, it is still an internal in srcu.h.

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
---
 include/linux/srcu.h |    2 ++
 kernel/srcu.c        |    6 ++----
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index a55ddb1..5cce128 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -78,6 +78,8 @@ int init_srcu_struct(struct srcu_struct *sp);
 
 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
+void process_srcu(struct work_struct *work);
+
 /**
  * call_srcu() - Queue a callback for invocation after an SRCU grace period
  * @sp: srcu_struct in queue the callback
diff --git a/kernel/srcu.c b/kernel/srcu.c
index 610486d..bfe4c5a 100644
--- a/kernel/srcu.c
+++ b/kernel/srcu.c
@@ -94,9 +94,6 @@ static inline void rcu_batch_move(struct rcu_batch *to, struct rcu_batch *from)
 	}
 }
 
-/* single-thread state-machine */
-static void process_srcu(struct work_struct *work);
-
 static int init_srcu_struct_fields(struct srcu_struct *sp)
 {
 	sp->completed = 0;
@@ -639,7 +636,7 @@ static void srcu_reschedule(struct srcu_struct *sp)
 /*
  * This is the work-queue function that handles SRCU grace periods.
  */
-static void process_srcu(struct work_struct *work)
+void process_srcu(struct work_struct *work)
 {
 	struct srcu_struct *sp;
 
@@ -650,3 +647,4 @@ static void process_srcu(struct work_struct *work)
 	srcu_invoke_callbacks(sp);
 	srcu_reschedule(sp);
 }
+EXPORT_SYMBOL_GPL(process_srcu);
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/4] srcu: add DEFINE_SRCU()
  2012-10-12 17:14 [PATCH 0/4] srcu: Add DEFINE_SRCU() Lai Jiangshan
  2012-10-12 17:14 ` [PATCH 1/4] srcu: add my name Lai Jiangshan
  2012-10-12 17:14 ` [PATCH 2/4] srcu: export process_srcu() Lai Jiangshan
@ 2012-10-12 17:14 ` Lai Jiangshan
  2012-10-15 21:56   ` Paul E. McKenney
  2012-10-12 17:14 ` [PATCH 4/4] rcutorture: use DEFINE_STATIC_SRCU() Lai Jiangshan
  2012-10-15 23:38 ` [PATCH 0/4] srcu: Add DEFINE_SRCU() Paul E. McKenney
  4 siblings, 1 reply; 9+ messages in thread
From: Lai Jiangshan @ 2012-10-12 17:14 UTC (permalink / raw)
  To: linux-kernel, Paul E. McKenney; +Cc: Lai Jiangshan

In old days, we have two different API sets for dynamic-allocated per_cpu data
and DEFINE_PER_CPU()-defined per_cpu data, and since we used
dynamic-allocated per_cpu data, we can't use DEFINE_PER_CPU()-defined
per_cpu data(otherwise we will introduce a lot of duplicated code.

In new days, we have only one API sets for both type of per_cpu data,
so we can use DEFINE_PER_CPU() for DEFINE_SRCU() which allows us
define and init srcu struct in build time and allows us use srcu APIs
in very early boot time.

We also provide DEFINE_STATIC_SRCU() which defines an internal srcu struct
inside a single *.c.

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
---
 include/linux/srcu.h |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index 5cce128..f986df1 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -42,6 +42,8 @@ struct rcu_batch {
 	struct rcu_head *head, **tail;
 };
 
+#define RCU_BATCH_INIT(name) { NULL, &(name.head) }
+
 struct srcu_struct {
 	unsigned completed;
 	struct srcu_struct_array __percpu *per_cpu_ref;
@@ -72,14 +74,42 @@ int __init_srcu_struct(struct srcu_struct *sp, const char *name,
 	__init_srcu_struct((sp), #sp, &__srcu_key); \
 })
 
+#define __SRCU_DEP_MAP_INIT(srcu_name)	.dep_map = { .name = #srcu_name },
 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
 int init_srcu_struct(struct srcu_struct *sp);
 
+#define __SRCU_DEP_MAP_INIT(srcu_name)
 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
 void process_srcu(struct work_struct *work);
 
+#define __SRCU_STRUCT_INIT(name)					\
+	{								\
+		.completed = -300,					\
+		.per_cpu_ref = &name##_srcu_array,			\
+		.queue_lock = __SPIN_LOCK_UNLOCKED(name.queue_lock),	\
+		.running = false,					\
+		.batch_queue = RCU_BATCH_INIT(name.batch_queue),	\
+		.batch_check0 = RCU_BATCH_INIT(name.batch_check0),	\
+		.batch_check1 = RCU_BATCH_INIT(name.batch_check1),	\
+		.batch_done = RCU_BATCH_INIT(name.batch_done),		\
+		.work = __DELAYED_WORK_INITIALIZER(name.work, process_srcu),\
+		__SRCU_DEP_MAP_INIT(name)				\
+	}
+
+/*
+ * define and init a srcu struct at build time.
+ * dont't call init_srcu_struct() nor cleanup_srcu_struct() on it.
+ */
+#define DEFINE_SRCU(name)						\
+	static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\
+	struct srcu_struct name = __SRCU_STRUCT_INIT(name);
+
+#define DEFINE_STATIC_SRCU(name)						\
+	static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\
+	static struct srcu_struct name = __SRCU_STRUCT_INIT(name);
+
 /**
  * call_srcu() - Queue a callback for invocation after an SRCU grace period
  * @sp: srcu_struct in queue the callback
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/4] rcutorture: use DEFINE_STATIC_SRCU()
  2012-10-12 17:14 [PATCH 0/4] srcu: Add DEFINE_SRCU() Lai Jiangshan
                   ` (2 preceding siblings ...)
  2012-10-12 17:14 ` [PATCH 3/4] srcu: add DEFINE_SRCU() Lai Jiangshan
@ 2012-10-12 17:14 ` Lai Jiangshan
  2012-10-12 19:06   ` Josh Triplett
  2012-10-15 23:38 ` [PATCH 0/4] srcu: Add DEFINE_SRCU() Paul E. McKenney
  4 siblings, 1 reply; 9+ messages in thread
From: Lai Jiangshan @ 2012-10-12 17:14 UTC (permalink / raw)
  To: linux-kernel, Paul E. McKenney; +Cc: Lai Jiangshan, Josh Triplett

use DEFINE_STATIC_SRCU() to simplify the rcutorture.c

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
---
 kernel/rcutorture.c |   41 ++++++-----------------------------------
 1 files changed, 6 insertions(+), 35 deletions(-)

diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 25b1503..7939edf 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -332,7 +332,6 @@ rcu_stutter_wait(char *title)
 
 struct rcu_torture_ops {
 	void (*init)(void);
-	void (*cleanup)(void);
 	int (*readlock)(void);
 	void (*read_delay)(struct rcu_random_state *rrsp);
 	void (*readunlock)(int idx);
@@ -424,7 +423,6 @@ static void rcu_torture_deferred_free(struct rcu_torture *p)
 
 static struct rcu_torture_ops rcu_ops = {
 	.init		= NULL,
-	.cleanup	= NULL,
 	.readlock	= rcu_torture_read_lock,
 	.read_delay	= rcu_read_delay,
 	.readunlock	= rcu_torture_read_unlock,
@@ -468,7 +466,6 @@ static void rcu_sync_torture_init(void)
 
 static struct rcu_torture_ops rcu_sync_ops = {
 	.init		= rcu_sync_torture_init,
-	.cleanup	= NULL,
 	.readlock	= rcu_torture_read_lock,
 	.read_delay	= rcu_read_delay,
 	.readunlock	= rcu_torture_read_unlock,
@@ -486,7 +483,6 @@ static struct rcu_torture_ops rcu_sync_ops = {
 
 static struct rcu_torture_ops rcu_expedited_ops = {
 	.init		= rcu_sync_torture_init,
-	.cleanup	= NULL,
 	.readlock	= rcu_torture_read_lock,
 	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
 	.readunlock	= rcu_torture_read_unlock,
@@ -529,7 +525,6 @@ static void rcu_bh_torture_deferred_free(struct rcu_torture *p)
 
 static struct rcu_torture_ops rcu_bh_ops = {
 	.init		= NULL,
-	.cleanup	= NULL,
 	.readlock	= rcu_bh_torture_read_lock,
 	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
 	.readunlock	= rcu_bh_torture_read_unlock,
@@ -546,7 +541,6 @@ static struct rcu_torture_ops rcu_bh_ops = {
 
 static struct rcu_torture_ops rcu_bh_sync_ops = {
 	.init		= rcu_sync_torture_init,
-	.cleanup	= NULL,
 	.readlock	= rcu_bh_torture_read_lock,
 	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
 	.readunlock	= rcu_bh_torture_read_unlock,
@@ -563,7 +557,6 @@ static struct rcu_torture_ops rcu_bh_sync_ops = {
 
 static struct rcu_torture_ops rcu_bh_expedited_ops = {
 	.init		= rcu_sync_torture_init,
-	.cleanup	= NULL,
 	.readlock	= rcu_bh_torture_read_lock,
 	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
 	.readunlock	= rcu_bh_torture_read_unlock,
@@ -582,19 +575,7 @@ static struct rcu_torture_ops rcu_bh_expedited_ops = {
  * Definitions for srcu torture testing.
  */
 
-static struct srcu_struct srcu_ctl;
-
-static void srcu_torture_init(void)
-{
-	init_srcu_struct(&srcu_ctl);
-	rcu_sync_torture_init();
-}
-
-static void srcu_torture_cleanup(void)
-{
-	synchronize_srcu(&srcu_ctl);
-	cleanup_srcu_struct(&srcu_ctl);
-}
+DEFINE_STATIC_SRCU(srcu_ctl);
 
 static int srcu_torture_read_lock(void) __acquires(&srcu_ctl)
 {
@@ -665,8 +646,7 @@ static int srcu_torture_stats(char *page)
 }
 
 static struct rcu_torture_ops srcu_ops = {
-	.init		= srcu_torture_init,
-	.cleanup	= srcu_torture_cleanup,
+	.init		= rcu_sync_torture_init,
 	.readlock	= srcu_torture_read_lock,
 	.read_delay	= srcu_read_delay,
 	.readunlock	= srcu_torture_read_unlock,
@@ -680,8 +660,7 @@ static struct rcu_torture_ops srcu_ops = {
 };
 
 static struct rcu_torture_ops srcu_sync_ops = {
-	.init		= srcu_torture_init,
-	.cleanup	= srcu_torture_cleanup,
+	.init		= rcu_sync_torture_init,
 	.readlock	= srcu_torture_read_lock,
 	.read_delay	= srcu_read_delay,
 	.readunlock	= srcu_torture_read_unlock,
@@ -705,8 +684,7 @@ static void srcu_torture_read_unlock_raw(int idx) __releases(&srcu_ctl)
 }
 
 static struct rcu_torture_ops srcu_raw_ops = {
-	.init		= srcu_torture_init,
-	.cleanup	= srcu_torture_cleanup,
+	.init		= rcu_sync_torture_init,
 	.readlock	= srcu_torture_read_lock_raw,
 	.read_delay	= srcu_read_delay,
 	.readunlock	= srcu_torture_read_unlock_raw,
@@ -720,8 +698,7 @@ static struct rcu_torture_ops srcu_raw_ops = {
 };
 
 static struct rcu_torture_ops srcu_raw_sync_ops = {
-	.init		= srcu_torture_init,
-	.cleanup	= srcu_torture_cleanup,
+	.init		= rcu_sync_torture_init,
 	.readlock	= srcu_torture_read_lock_raw,
 	.read_delay	= srcu_read_delay,
 	.readunlock	= srcu_torture_read_unlock_raw,
@@ -740,8 +717,7 @@ static void srcu_torture_synchronize_expedited(void)
 }
 
 static struct rcu_torture_ops srcu_expedited_ops = {
-	.init		= srcu_torture_init,
-	.cleanup	= srcu_torture_cleanup,
+	.init		= rcu_sync_torture_init,
 	.readlock	= srcu_torture_read_lock,
 	.read_delay	= srcu_read_delay,
 	.readunlock	= srcu_torture_read_unlock,
@@ -776,7 +752,6 @@ static void rcu_sched_torture_deferred_free(struct rcu_torture *p)
 
 static struct rcu_torture_ops sched_ops = {
 	.init		= rcu_sync_torture_init,
-	.cleanup	= NULL,
 	.readlock	= sched_torture_read_lock,
 	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
 	.readunlock	= sched_torture_read_unlock,
@@ -792,7 +767,6 @@ static struct rcu_torture_ops sched_ops = {
 
 static struct rcu_torture_ops sched_sync_ops = {
 	.init		= rcu_sync_torture_init,
-	.cleanup	= NULL,
 	.readlock	= sched_torture_read_lock,
 	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
 	.readunlock	= sched_torture_read_unlock,
@@ -807,7 +781,6 @@ static struct rcu_torture_ops sched_sync_ops = {
 
 static struct rcu_torture_ops sched_expedited_ops = {
 	.init		= rcu_sync_torture_init,
-	.cleanup	= NULL,
 	.readlock	= sched_torture_read_lock,
 	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
 	.readunlock	= sched_torture_read_unlock,
@@ -1903,8 +1876,6 @@ rcu_torture_cleanup(void)
 
 	rcu_torture_stats_print();  /* -After- the stats thread is stopped! */
 
-	if (cur_ops->cleanup)
-		cur_ops->cleanup();
 	if (atomic_read(&n_rcu_torture_error) || n_rcu_torture_barrier_error)
 		rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE");
 	else if (n_online_successes != n_online_attempts ||
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 4/4] rcutorture: use DEFINE_STATIC_SRCU()
  2012-10-12 17:14 ` [PATCH 4/4] rcutorture: use DEFINE_STATIC_SRCU() Lai Jiangshan
@ 2012-10-12 19:06   ` Josh Triplett
  0 siblings, 0 replies; 9+ messages in thread
From: Josh Triplett @ 2012-10-12 19:06 UTC (permalink / raw)
  To: Lai Jiangshan; +Cc: linux-kernel, Paul E. McKenney

On Sat, Oct 13, 2012 at 01:14:17AM +0800, Lai Jiangshan wrote:
> use DEFINE_STATIC_SRCU() to simplify the rcutorture.c
> 
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>

Reviewed-by: Josh Triplett <josh@joshtriplett.org>

> ---
>  kernel/rcutorture.c |   41 ++++++-----------------------------------
>  1 files changed, 6 insertions(+), 35 deletions(-)
> 
> diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
> index 25b1503..7939edf 100644
> --- a/kernel/rcutorture.c
> +++ b/kernel/rcutorture.c
> @@ -332,7 +332,6 @@ rcu_stutter_wait(char *title)
>  
>  struct rcu_torture_ops {
>  	void (*init)(void);
> -	void (*cleanup)(void);
>  	int (*readlock)(void);
>  	void (*read_delay)(struct rcu_random_state *rrsp);
>  	void (*readunlock)(int idx);
> @@ -424,7 +423,6 @@ static void rcu_torture_deferred_free(struct rcu_torture *p)
>  
>  static struct rcu_torture_ops rcu_ops = {
>  	.init		= NULL,
> -	.cleanup	= NULL,
>  	.readlock	= rcu_torture_read_lock,
>  	.read_delay	= rcu_read_delay,
>  	.readunlock	= rcu_torture_read_unlock,
> @@ -468,7 +466,6 @@ static void rcu_sync_torture_init(void)
>  
>  static struct rcu_torture_ops rcu_sync_ops = {
>  	.init		= rcu_sync_torture_init,
> -	.cleanup	= NULL,
>  	.readlock	= rcu_torture_read_lock,
>  	.read_delay	= rcu_read_delay,
>  	.readunlock	= rcu_torture_read_unlock,
> @@ -486,7 +483,6 @@ static struct rcu_torture_ops rcu_sync_ops = {
>  
>  static struct rcu_torture_ops rcu_expedited_ops = {
>  	.init		= rcu_sync_torture_init,
> -	.cleanup	= NULL,
>  	.readlock	= rcu_torture_read_lock,
>  	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
>  	.readunlock	= rcu_torture_read_unlock,
> @@ -529,7 +525,6 @@ static void rcu_bh_torture_deferred_free(struct rcu_torture *p)
>  
>  static struct rcu_torture_ops rcu_bh_ops = {
>  	.init		= NULL,
> -	.cleanup	= NULL,
>  	.readlock	= rcu_bh_torture_read_lock,
>  	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
>  	.readunlock	= rcu_bh_torture_read_unlock,
> @@ -546,7 +541,6 @@ static struct rcu_torture_ops rcu_bh_ops = {
>  
>  static struct rcu_torture_ops rcu_bh_sync_ops = {
>  	.init		= rcu_sync_torture_init,
> -	.cleanup	= NULL,
>  	.readlock	= rcu_bh_torture_read_lock,
>  	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
>  	.readunlock	= rcu_bh_torture_read_unlock,
> @@ -563,7 +557,6 @@ static struct rcu_torture_ops rcu_bh_sync_ops = {
>  
>  static struct rcu_torture_ops rcu_bh_expedited_ops = {
>  	.init		= rcu_sync_torture_init,
> -	.cleanup	= NULL,
>  	.readlock	= rcu_bh_torture_read_lock,
>  	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
>  	.readunlock	= rcu_bh_torture_read_unlock,
> @@ -582,19 +575,7 @@ static struct rcu_torture_ops rcu_bh_expedited_ops = {
>   * Definitions for srcu torture testing.
>   */
>  
> -static struct srcu_struct srcu_ctl;
> -
> -static void srcu_torture_init(void)
> -{
> -	init_srcu_struct(&srcu_ctl);
> -	rcu_sync_torture_init();
> -}
> -
> -static void srcu_torture_cleanup(void)
> -{
> -	synchronize_srcu(&srcu_ctl);
> -	cleanup_srcu_struct(&srcu_ctl);
> -}
> +DEFINE_STATIC_SRCU(srcu_ctl);
>  
>  static int srcu_torture_read_lock(void) __acquires(&srcu_ctl)
>  {
> @@ -665,8 +646,7 @@ static int srcu_torture_stats(char *page)
>  }
>  
>  static struct rcu_torture_ops srcu_ops = {
> -	.init		= srcu_torture_init,
> -	.cleanup	= srcu_torture_cleanup,
> +	.init		= rcu_sync_torture_init,
>  	.readlock	= srcu_torture_read_lock,
>  	.read_delay	= srcu_read_delay,
>  	.readunlock	= srcu_torture_read_unlock,
> @@ -680,8 +660,7 @@ static struct rcu_torture_ops srcu_ops = {
>  };
>  
>  static struct rcu_torture_ops srcu_sync_ops = {
> -	.init		= srcu_torture_init,
> -	.cleanup	= srcu_torture_cleanup,
> +	.init		= rcu_sync_torture_init,
>  	.readlock	= srcu_torture_read_lock,
>  	.read_delay	= srcu_read_delay,
>  	.readunlock	= srcu_torture_read_unlock,
> @@ -705,8 +684,7 @@ static void srcu_torture_read_unlock_raw(int idx) __releases(&srcu_ctl)
>  }
>  
>  static struct rcu_torture_ops srcu_raw_ops = {
> -	.init		= srcu_torture_init,
> -	.cleanup	= srcu_torture_cleanup,
> +	.init		= rcu_sync_torture_init,
>  	.readlock	= srcu_torture_read_lock_raw,
>  	.read_delay	= srcu_read_delay,
>  	.readunlock	= srcu_torture_read_unlock_raw,
> @@ -720,8 +698,7 @@ static struct rcu_torture_ops srcu_raw_ops = {
>  };
>  
>  static struct rcu_torture_ops srcu_raw_sync_ops = {
> -	.init		= srcu_torture_init,
> -	.cleanup	= srcu_torture_cleanup,
> +	.init		= rcu_sync_torture_init,
>  	.readlock	= srcu_torture_read_lock_raw,
>  	.read_delay	= srcu_read_delay,
>  	.readunlock	= srcu_torture_read_unlock_raw,
> @@ -740,8 +717,7 @@ static void srcu_torture_synchronize_expedited(void)
>  }
>  
>  static struct rcu_torture_ops srcu_expedited_ops = {
> -	.init		= srcu_torture_init,
> -	.cleanup	= srcu_torture_cleanup,
> +	.init		= rcu_sync_torture_init,
>  	.readlock	= srcu_torture_read_lock,
>  	.read_delay	= srcu_read_delay,
>  	.readunlock	= srcu_torture_read_unlock,
> @@ -776,7 +752,6 @@ static void rcu_sched_torture_deferred_free(struct rcu_torture *p)
>  
>  static struct rcu_torture_ops sched_ops = {
>  	.init		= rcu_sync_torture_init,
> -	.cleanup	= NULL,
>  	.readlock	= sched_torture_read_lock,
>  	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
>  	.readunlock	= sched_torture_read_unlock,
> @@ -792,7 +767,6 @@ static struct rcu_torture_ops sched_ops = {
>  
>  static struct rcu_torture_ops sched_sync_ops = {
>  	.init		= rcu_sync_torture_init,
> -	.cleanup	= NULL,
>  	.readlock	= sched_torture_read_lock,
>  	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
>  	.readunlock	= sched_torture_read_unlock,
> @@ -807,7 +781,6 @@ static struct rcu_torture_ops sched_sync_ops = {
>  
>  static struct rcu_torture_ops sched_expedited_ops = {
>  	.init		= rcu_sync_torture_init,
> -	.cleanup	= NULL,
>  	.readlock	= sched_torture_read_lock,
>  	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
>  	.readunlock	= sched_torture_read_unlock,
> @@ -1903,8 +1876,6 @@ rcu_torture_cleanup(void)
>  
>  	rcu_torture_stats_print();  /* -After- the stats thread is stopped! */
>  
> -	if (cur_ops->cleanup)
> -		cur_ops->cleanup();
>  	if (atomic_read(&n_rcu_torture_error) || n_rcu_torture_barrier_error)
>  		rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE");
>  	else if (n_online_successes != n_online_attempts ||
> -- 
> 1.7.7.6
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/4] srcu: add DEFINE_SRCU()
  2012-10-12 17:14 ` [PATCH 3/4] srcu: add DEFINE_SRCU() Lai Jiangshan
@ 2012-10-15 21:56   ` Paul E. McKenney
  2012-10-15 22:40     ` Paul E. McKenney
  0 siblings, 1 reply; 9+ messages in thread
From: Paul E. McKenney @ 2012-10-15 21:56 UTC (permalink / raw)
  To: Lai Jiangshan; +Cc: linux-kernel

On Sat, Oct 13, 2012 at 01:14:16AM +0800, Lai Jiangshan wrote:
> In old days, we have two different API sets for dynamic-allocated per_cpu data
> and DEFINE_PER_CPU()-defined per_cpu data, and since we used
> dynamic-allocated per_cpu data, we can't use DEFINE_PER_CPU()-defined
> per_cpu data(otherwise we will introduce a lot of duplicated code.
> 
> In new days, we have only one API sets for both type of per_cpu data,
> so we can use DEFINE_PER_CPU() for DEFINE_SRCU() which allows us
> define and init srcu struct in build time and allows us use srcu APIs
> in very early boot time.
> 
> We also provide DEFINE_STATIC_SRCU() which defines an internal srcu struct
> inside a single *.c.
> 
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
> ---
>  include/linux/srcu.h |   30 ++++++++++++++++++++++++++++++
>  1 files changed, 30 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> index 5cce128..f986df1 100644
> --- a/include/linux/srcu.h
> +++ b/include/linux/srcu.h
> @@ -42,6 +42,8 @@ struct rcu_batch {
>  	struct rcu_head *head, **tail;
>  };
> 
> +#define RCU_BATCH_INIT(name) { NULL, &(name.head) }
> +
>  struct srcu_struct {
>  	unsigned completed;
>  	struct srcu_struct_array __percpu *per_cpu_ref;
> @@ -72,14 +74,42 @@ int __init_srcu_struct(struct srcu_struct *sp, const char *name,
>  	__init_srcu_struct((sp), #sp, &__srcu_key); \
>  })
> 
> +#define __SRCU_DEP_MAP_INIT(srcu_name)	.dep_map = { .name = #srcu_name },
>  #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
> 
>  int init_srcu_struct(struct srcu_struct *sp);
> 
> +#define __SRCU_DEP_MAP_INIT(srcu_name)
>  #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
> 
>  void process_srcu(struct work_struct *work);
> 
> +#define __SRCU_STRUCT_INIT(name)					\
> +	{								\
> +		.completed = -300,					\
> +		.per_cpu_ref = &name##_srcu_array,			\
> +		.queue_lock = __SPIN_LOCK_UNLOCKED(name.queue_lock),	\
> +		.running = false,					\
> +		.batch_queue = RCU_BATCH_INIT(name.batch_queue),	\
> +		.batch_check0 = RCU_BATCH_INIT(name.batch_check0),	\
> +		.batch_check1 = RCU_BATCH_INIT(name.batch_check1),	\
> +		.batch_done = RCU_BATCH_INIT(name.batch_done),		\
> +		.work = __DELAYED_WORK_INITIALIZER(name.work, process_srcu),\
> +		__SRCU_DEP_MAP_INIT(name)				\
> +	}
> +
> +/*
> + * define and init a srcu struct at build time.
> + * dont't call init_srcu_struct() nor cleanup_srcu_struct() on it.
> + */
> +#define DEFINE_SRCU(name)						\
> +	static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\
> +	struct srcu_struct name = __SRCU_STRUCT_INIT(name);
> +
> +#define DEFINE_STATIC_SRCU(name)						\
> +	static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\
> +	static struct srcu_struct name = __SRCU_STRUCT_INIT(name);
> +

Why not collapse DEFINE_SRCU() and DEFINE_STATIC_SRCU() as follows?

+#define DEFINE_SRCU(name)						\
+	struct srcu_struct name = __SRCU_STRUCT_INIT(name);		\
+	static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);

Then "static DEFINE_SRCU(foo)" would create a static srcu_struct without
the need for a separate DEFINE_STATIC_SRCU().

							Thanx, Paul

>  /**
>   * call_srcu() - Queue a callback for invocation after an SRCU grace period
>   * @sp: srcu_struct in queue the callback
> -- 
> 1.7.7.6
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/4] srcu: add DEFINE_SRCU()
  2012-10-15 21:56   ` Paul E. McKenney
@ 2012-10-15 22:40     ` Paul E. McKenney
  0 siblings, 0 replies; 9+ messages in thread
From: Paul E. McKenney @ 2012-10-15 22:40 UTC (permalink / raw)
  To: Lai Jiangshan; +Cc: linux-kernel

On Mon, Oct 15, 2012 at 02:56:07PM -0700, Paul E. McKenney wrote:
> On Sat, Oct 13, 2012 at 01:14:16AM +0800, Lai Jiangshan wrote:
> > In old days, we have two different API sets for dynamic-allocated per_cpu data
> > and DEFINE_PER_CPU()-defined per_cpu data, and since we used
> > dynamic-allocated per_cpu data, we can't use DEFINE_PER_CPU()-defined
> > per_cpu data(otherwise we will introduce a lot of duplicated code.
> > 
> > In new days, we have only one API sets for both type of per_cpu data,
> > so we can use DEFINE_PER_CPU() for DEFINE_SRCU() which allows us
> > define and init srcu struct in build time and allows us use srcu APIs
> > in very early boot time.
> > 
> > We also provide DEFINE_STATIC_SRCU() which defines an internal srcu struct
> > inside a single *.c.
> > 
> > Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
> > ---
> >  include/linux/srcu.h |   30 ++++++++++++++++++++++++++++++
> >  1 files changed, 30 insertions(+), 0 deletions(-)
> > 
> > diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> > index 5cce128..f986df1 100644
> > --- a/include/linux/srcu.h
> > +++ b/include/linux/srcu.h
> > @@ -42,6 +42,8 @@ struct rcu_batch {
> >  	struct rcu_head *head, **tail;
> >  };
> > 
> > +#define RCU_BATCH_INIT(name) { NULL, &(name.head) }
> > +
> >  struct srcu_struct {
> >  	unsigned completed;
> >  	struct srcu_struct_array __percpu *per_cpu_ref;
> > @@ -72,14 +74,42 @@ int __init_srcu_struct(struct srcu_struct *sp, const char *name,
> >  	__init_srcu_struct((sp), #sp, &__srcu_key); \
> >  })
> > 
> > +#define __SRCU_DEP_MAP_INIT(srcu_name)	.dep_map = { .name = #srcu_name },
> >  #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
> > 
> >  int init_srcu_struct(struct srcu_struct *sp);
> > 
> > +#define __SRCU_DEP_MAP_INIT(srcu_name)
> >  #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
> > 
> >  void process_srcu(struct work_struct *work);
> > 
> > +#define __SRCU_STRUCT_INIT(name)					\
> > +	{								\
> > +		.completed = -300,					\
> > +		.per_cpu_ref = &name##_srcu_array,			\
> > +		.queue_lock = __SPIN_LOCK_UNLOCKED(name.queue_lock),	\
> > +		.running = false,					\
> > +		.batch_queue = RCU_BATCH_INIT(name.batch_queue),	\
> > +		.batch_check0 = RCU_BATCH_INIT(name.batch_check0),	\
> > +		.batch_check1 = RCU_BATCH_INIT(name.batch_check1),	\
> > +		.batch_done = RCU_BATCH_INIT(name.batch_done),		\
> > +		.work = __DELAYED_WORK_INITIALIZER(name.work, process_srcu),\
> > +		__SRCU_DEP_MAP_INIT(name)				\
> > +	}
> > +
> > +/*
> > + * define and init a srcu struct at build time.
> > + * dont't call init_srcu_struct() nor cleanup_srcu_struct() on it.
> > + */
> > +#define DEFINE_SRCU(name)						\
> > +	static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\
> > +	struct srcu_struct name = __SRCU_STRUCT_INIT(name);
> > +
> > +#define DEFINE_STATIC_SRCU(name)						\
> > +	static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\
> > +	static struct srcu_struct name = __SRCU_STRUCT_INIT(name);
> > +
> 
> Why not collapse DEFINE_SRCU() and DEFINE_STATIC_SRCU() as follows?
> 
> +#define DEFINE_SRCU(name)						\
> +	struct srcu_struct name = __SRCU_STRUCT_INIT(name);		\
> +	static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);
> 
> Then "static DEFINE_SRCU(foo)" would create a static srcu_struct without
> the need for a separate DEFINE_STATIC_SRCU().

Never mind!!!  This of course results in a forward reference and a
compiler warning...

							Thanx, Paul

> >  /**
> >   * call_srcu() - Queue a callback for invocation after an SRCU grace period
> >   * @sp: srcu_struct in queue the callback
> > -- 
> > 1.7.7.6
> > 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/4] srcu: Add DEFINE_SRCU()
  2012-10-12 17:14 [PATCH 0/4] srcu: Add DEFINE_SRCU() Lai Jiangshan
                   ` (3 preceding siblings ...)
  2012-10-12 17:14 ` [PATCH 4/4] rcutorture: use DEFINE_STATIC_SRCU() Lai Jiangshan
@ 2012-10-15 23:38 ` Paul E. McKenney
  4 siblings, 0 replies; 9+ messages in thread
From: Paul E. McKenney @ 2012-10-15 23:38 UTC (permalink / raw)
  To: Lai Jiangshan; +Cc: linux-kernel

On Sat, Oct 13, 2012 at 01:14:13AM +0800, Lai Jiangshan wrote:
> These patches add a simple DEFINE_SRCU() which define and init
> the srcu struct in build time, and allow us use srcu in very early
> boot time.

So queue for 3.8, thank you!

						Thanx, Paul

> Lai Jiangshan (4):
>   srcu: add my name
>   srcu: export process_srcu()
>   srcu: add DEFINE_SRCU
>   rcutorture: use DEFINE_STATIC_SRCU()
> 
>  include/linux/srcu.h |   34 ++++++++++++++++++++++++++++++++++
>  kernel/rcutorture.c  |   41 ++++++-----------------------------------
>  kernel/srcu.c        |    8 ++++----
>  3 files changed, 44 insertions(+), 39 deletions(-)
> 
> -- 
> 1.7.7.6
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-10-15 23:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-12 17:14 [PATCH 0/4] srcu: Add DEFINE_SRCU() Lai Jiangshan
2012-10-12 17:14 ` [PATCH 1/4] srcu: add my name Lai Jiangshan
2012-10-12 17:14 ` [PATCH 2/4] srcu: export process_srcu() Lai Jiangshan
2012-10-12 17:14 ` [PATCH 3/4] srcu: add DEFINE_SRCU() Lai Jiangshan
2012-10-15 21:56   ` Paul E. McKenney
2012-10-15 22:40     ` Paul E. McKenney
2012-10-12 17:14 ` [PATCH 4/4] rcutorture: use DEFINE_STATIC_SRCU() Lai Jiangshan
2012-10-12 19:06   ` Josh Triplett
2012-10-15 23:38 ` [PATCH 0/4] srcu: Add DEFINE_SRCU() Paul E. McKenney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox