]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/commitdiff
srcu: Add DEFINE_SRCU()
authorLai Jiangshan <laijs@cn.fujitsu.com>
Fri, 12 Oct 2012 17:14:16 +0000 (01:14 +0800)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Sat, 27 Oct 2012 22:38:29 +0000 (15:38 -0700)
In old days, we had two different API sets for dynamic-allocated per-CPU
data and DEFINE_PER_CPU()-defined per_cpu data, and because SRCU used
dynamic-allocated per-CPU data, its srcu_struct structures cannot be
declared statically.  This commit therefore introduces DEFINE_SRCU()
and DEFINE_STATIC_SRCU() to allow statically declared SRCU structures,
using the new static per-CPU interfaces.

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
[ paulmck: Updated for __DELAYED_WORK_INITIALIZER() added argument,
   fixed whitespace issue. ]

include/linux/srcu.h

index 5cce128f196c02c24fc242c79bd85606110629f2..6eb691b083581ff88ffd9e7c3da73bc5aa2170fd 100644 (file)
@@ -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, 0),\
+               __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