|
@@ -40,6 +40,7 @@
|
|
#include <linux/seqlock.h>
|
|
#include <linux/seqlock.h>
|
|
#include <linux/lockdep.h>
|
|
#include <linux/lockdep.h>
|
|
#include <linux/completion.h>
|
|
#include <linux/completion.h>
|
|
|
|
+#include <linux/debugobjects.h>
|
|
|
|
|
|
#ifdef CONFIG_RCU_TORTURE_TEST
|
|
#ifdef CONFIG_RCU_TORTURE_TEST
|
|
extern int rcutorture_runnable; /* for sysctl */
|
|
extern int rcutorture_runnable; /* for sysctl */
|
|
@@ -79,6 +80,16 @@ extern void rcu_init(void);
|
|
(ptr)->next = NULL; (ptr)->func = NULL; \
|
|
(ptr)->next = NULL; (ptr)->func = NULL; \
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * init_rcu_head_on_stack()/destroy_rcu_head_on_stack() are needed for dynamic
|
|
|
|
+ * initialization and destruction of rcu_head on the stack. rcu_head structures
|
|
|
|
+ * allocated dynamically in the heap or defined statically don't need any
|
|
|
|
+ * initialization.
|
|
|
|
+ */
|
|
|
|
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
|
|
|
|
+extern void init_rcu_head_on_stack(struct rcu_head *head);
|
|
|
|
+extern void destroy_rcu_head_on_stack(struct rcu_head *head);
|
|
|
|
+#else /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
|
|
static inline void init_rcu_head_on_stack(struct rcu_head *head)
|
|
static inline void init_rcu_head_on_stack(struct rcu_head *head)
|
|
{
|
|
{
|
|
}
|
|
}
|
|
@@ -86,6 +97,7 @@ static inline void init_rcu_head_on_stack(struct rcu_head *head)
|
|
static inline void destroy_rcu_head_on_stack(struct rcu_head *head)
|
|
static inline void destroy_rcu_head_on_stack(struct rcu_head *head)
|
|
{
|
|
{
|
|
}
|
|
}
|
|
|
|
+#endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
|
|
|
|
|
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
|
|
|
|
@@ -517,4 +529,74 @@ extern void call_rcu(struct rcu_head *head,
|
|
extern void call_rcu_bh(struct rcu_head *head,
|
|
extern void call_rcu_bh(struct rcu_head *head,
|
|
void (*func)(struct rcu_head *head));
|
|
void (*func)(struct rcu_head *head));
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally
|
|
|
|
+ * by call_rcu() and rcu callback execution, and are therefore not part of the
|
|
|
|
+ * RCU API. Leaving in rcupdate.h because they are used by all RCU flavors.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
|
|
|
|
+# define STATE_RCU_HEAD_READY 0
|
|
|
|
+# define STATE_RCU_HEAD_QUEUED 1
|
|
|
|
+
|
|
|
|
+extern struct debug_obj_descr rcuhead_debug_descr;
|
|
|
|
+
|
|
|
|
+static inline void debug_rcu_head_queue(struct rcu_head *head)
|
|
|
|
+{
|
|
|
|
+ debug_object_activate(head, &rcuhead_debug_descr);
|
|
|
|
+ debug_object_active_state(head, &rcuhead_debug_descr,
|
|
|
|
+ STATE_RCU_HEAD_READY,
|
|
|
|
+ STATE_RCU_HEAD_QUEUED);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void debug_rcu_head_unqueue(struct rcu_head *head)
|
|
|
|
+{
|
|
|
|
+ debug_object_active_state(head, &rcuhead_debug_descr,
|
|
|
|
+ STATE_RCU_HEAD_QUEUED,
|
|
|
|
+ STATE_RCU_HEAD_READY);
|
|
|
|
+ debug_object_deactivate(head, &rcuhead_debug_descr);
|
|
|
|
+}
|
|
|
|
+#else /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
|
|
|
|
+static inline void debug_rcu_head_queue(struct rcu_head *head)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void debug_rcu_head_unqueue(struct rcu_head *head)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+#endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
|
|
|
|
+
|
|
|
|
+#ifndef CONFIG_PROVE_RCU
|
|
|
|
+#define __do_rcu_dereference_check(c) do { } while (0)
|
|
|
|
+#endif /* #ifdef CONFIG_PROVE_RCU */
|
|
|
|
+
|
|
|
|
+#define __rcu_dereference_index_check(p, c) \
|
|
|
|
+ ({ \
|
|
|
|
+ typeof(p) _________p1 = ACCESS_ONCE(p); \
|
|
|
|
+ __do_rcu_dereference_check(c); \
|
|
|
|
+ smp_read_barrier_depends(); \
|
|
|
|
+ (_________p1); \
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * rcu_dereference_index_check() - rcu_dereference for indices with debug checking
|
|
|
|
+ * @p: The pointer to read, prior to dereferencing
|
|
|
|
+ * @c: The conditions under which the dereference will take place
|
|
|
|
+ *
|
|
|
|
+ * Similar to rcu_dereference_check(), but omits the sparse checking.
|
|
|
|
+ * This allows rcu_dereference_index_check() to be used on integers,
|
|
|
|
+ * which can then be used as array indices. Attempting to use
|
|
|
|
+ * rcu_dereference_check() on an integer will give compiler warnings
|
|
|
|
+ * because the sparse address-space mechanism relies on dereferencing
|
|
|
|
+ * the RCU-protected pointer. Dereferencing integers is not something
|
|
|
|
+ * that even gcc will put up with.
|
|
|
|
+ *
|
|
|
|
+ * Note that this function does not implicitly check for RCU read-side
|
|
|
|
+ * critical sections. If this function gains lots of uses, it might
|
|
|
|
+ * make sense to provide versions for each flavor of RCU, but it does
|
|
|
|
+ * not make sense as of early 2010.
|
|
|
|
+ */
|
|
|
|
+#define rcu_dereference_index_check(p, c) \
|
|
|
|
+ __rcu_dereference_index_check((p), (c))
|
|
|
|
+
|
|
#endif /* __LINUX_RCUPDATE_H */
|
|
#endif /* __LINUX_RCUPDATE_H */
|