diff options
author | Lai Jiangshan <laijs@cn.fujitsu.com> | 2012-10-12 13:14:16 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2012-10-27 18:38:29 -0400 |
commit | 55c6659afaa6fd79a3b5a7c2b42bb87e0c11209d (patch) | |
tree | 47e14a8826659b8ce13b1e0ae011e60576a2cc0d | |
parent | f2ebfbc991044fd5b89d4529741d7500feb37fbd (diff) |
srcu: Add DEFINE_SRCU()
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. ]
-rw-r--r-- | 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 5cce128f196c..6eb691b08358 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h | |||
@@ -42,6 +42,8 @@ struct rcu_batch { | |||
42 | struct rcu_head *head, **tail; | 42 | struct rcu_head *head, **tail; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | #define RCU_BATCH_INIT(name) { NULL, &(name.head) } | ||
46 | |||
45 | struct srcu_struct { | 47 | struct srcu_struct { |
46 | unsigned completed; | 48 | unsigned completed; |
47 | struct srcu_struct_array __percpu *per_cpu_ref; | 49 | struct srcu_struct_array __percpu *per_cpu_ref; |
@@ -72,14 +74,42 @@ int __init_srcu_struct(struct srcu_struct *sp, const char *name, | |||
72 | __init_srcu_struct((sp), #sp, &__srcu_key); \ | 74 | __init_srcu_struct((sp), #sp, &__srcu_key); \ |
73 | }) | 75 | }) |
74 | 76 | ||
77 | #define __SRCU_DEP_MAP_INIT(srcu_name) .dep_map = { .name = #srcu_name }, | ||
75 | #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ | 78 | #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ |
76 | 79 | ||
77 | int init_srcu_struct(struct srcu_struct *sp); | 80 | int init_srcu_struct(struct srcu_struct *sp); |
78 | 81 | ||
82 | #define __SRCU_DEP_MAP_INIT(srcu_name) | ||
79 | #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ | 83 | #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ |
80 | 84 | ||
81 | void process_srcu(struct work_struct *work); | 85 | void process_srcu(struct work_struct *work); |
82 | 86 | ||
87 | #define __SRCU_STRUCT_INIT(name) \ | ||
88 | { \ | ||
89 | .completed = -300, \ | ||
90 | .per_cpu_ref = &name##_srcu_array, \ | ||
91 | .queue_lock = __SPIN_LOCK_UNLOCKED(name.queue_lock), \ | ||
92 | .running = false, \ | ||
93 | .batch_queue = RCU_BATCH_INIT(name.batch_queue), \ | ||
94 | .batch_check0 = RCU_BATCH_INIT(name.batch_check0), \ | ||
95 | .batch_check1 = RCU_BATCH_INIT(name.batch_check1), \ | ||
96 | .batch_done = RCU_BATCH_INIT(name.batch_done), \ | ||
97 | .work = __DELAYED_WORK_INITIALIZER(name.work, process_srcu, 0),\ | ||
98 | __SRCU_DEP_MAP_INIT(name) \ | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * define and init a srcu struct at build time. | ||
103 | * dont't call init_srcu_struct() nor cleanup_srcu_struct() on it. | ||
104 | */ | ||
105 | #define DEFINE_SRCU(name) \ | ||
106 | static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\ | ||
107 | struct srcu_struct name = __SRCU_STRUCT_INIT(name); | ||
108 | |||
109 | #define DEFINE_STATIC_SRCU(name) \ | ||
110 | static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\ | ||
111 | static struct srcu_struct name = __SRCU_STRUCT_INIT(name); | ||
112 | |||
83 | /** | 113 | /** |
84 | * call_srcu() - Queue a callback for invocation after an SRCU grace period | 114 | * call_srcu() - Queue a callback for invocation after an SRCU grace period |
85 | * @sp: srcu_struct in queue the callback | 115 | * @sp: srcu_struct in queue the callback |