Commit 55c6659afaa6fd79a3b5a7c2b42bb87e0c11209d

Authored by Lai Jiangshan
Committed by Paul E. McKenney
1 parent f2ebfbc991

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. ]

Showing 1 changed file with 30 additions and 0 deletions Side-by-side Diff

include/linux/srcu.h
... ... @@ -42,6 +42,8 @@
42 42 struct rcu_head *head, **tail;
43 43 };
44 44  
  45 +#define RCU_BATCH_INIT(name) { NULL, &(name.head) }
  46 +
45 47 struct srcu_struct {
46 48 unsigned completed;
47 49 struct srcu_struct_array __percpu *per_cpu_ref;
48 50  
49 51  
... ... @@ -72,13 +74,41 @@
72 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 78 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
76 79  
77 80 int init_srcu_struct(struct srcu_struct *sp);
78 81  
  82 +#define __SRCU_DEP_MAP_INIT(srcu_name)
79 83 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
80 84  
81 85 void process_srcu(struct work_struct *work);
  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);
82 112  
83 113 /**
84 114 * call_srcu() - Queue a callback for invocation after an SRCU grace period