| From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| Subject: rbtree: don't include the rcu header |
| |
| The RCU header pulls in spinlock.h and fails due not yet defined types: |
| |
| |In file included from include/linux/spinlock.h:275:0, |
| | from include/linux/rcupdate.h:38, |
| | from include/linux/rbtree.h:34, |
| | from include/linux/rtmutex.h:17, |
| | from include/linux/spinlock_types.h:18, |
| | from kernel/bounds.c:13: |
| |include/linux/rwlock_rt.h:16:38: error: unknown type name ‘rwlock_t’ |
| | extern void __lockfunc rt_write_lock(rwlock_t *rwlock); |
| | ^ |
| |
| This patch moves the required RCU function from the rcupdate.h header file into |
| a new header file which can be included by both users. |
| |
| Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| --- |
| include/linux/rbtree.h | 2 - |
| include/linux/rcu_assign_pointer.h | 54 +++++++++++++++++++++++++++++++++++++ |
| include/linux/rcupdate.h | 49 --------------------------------- |
| 3 files changed, 56 insertions(+), 49 deletions(-) |
| |
| --- a/include/linux/rbtree.h |
| +++ b/include/linux/rbtree.h |
| @@ -31,7 +31,7 @@ |
| |
| #include <linux/kernel.h> |
| #include <linux/stddef.h> |
| -#include <linux/rcupdate.h> |
| +#include <linux/rcu_assign_pointer.h> |
| |
| struct rb_node { |
| unsigned long __rb_parent_color; |
| --- /dev/null |
| +++ b/include/linux/rcu_assign_pointer.h |
| @@ -0,0 +1,54 @@ |
| +#ifndef __LINUX_RCU_ASSIGN_POINTER_H__ |
| +#define __LINUX_RCU_ASSIGN_POINTER_H__ |
| +#include <linux/compiler.h> |
| +#include <asm/barrier.h> |
| + |
| +/** |
| + * RCU_INITIALIZER() - statically initialize an RCU-protected global variable |
| + * @v: The value to statically initialize with. |
| + */ |
| +#define RCU_INITIALIZER(v) (typeof(*(v)) __force __rcu *)(v) |
| + |
| +/** |
| + * rcu_assign_pointer() - assign to RCU-protected pointer |
| + * @p: pointer to assign to |
| + * @v: value to assign (publish) |
| + * |
| + * Assigns the specified value to the specified RCU-protected |
| + * pointer, ensuring that any concurrent RCU readers will see |
| + * any prior initialization. |
| + * |
| + * Inserts memory barriers on architectures that require them |
| + * (which is most of them), and also prevents the compiler from |
| + * reordering the code that initializes the structure after the pointer |
| + * assignment. More importantly, this call documents which pointers |
| + * will be dereferenced by RCU read-side code. |
| + * |
| + * In some special cases, you may use RCU_INIT_POINTER() instead |
| + * of rcu_assign_pointer(). RCU_INIT_POINTER() is a bit faster due |
| + * to the fact that it does not constrain either the CPU or the compiler. |
| + * That said, using RCU_INIT_POINTER() when you should have used |
| + * rcu_assign_pointer() is a very bad thing that results in |
| + * impossible-to-diagnose memory corruption. So please be careful. |
| + * See the RCU_INIT_POINTER() comment header for details. |
| + * |
| + * Note that rcu_assign_pointer() evaluates each of its arguments only |
| + * once, appearances notwithstanding. One of the "extra" evaluations |
| + * is in typeof() and the other visible only to sparse (__CHECKER__), |
| + * neither of which actually execute the argument. As with most cpp |
| + * macros, this execute-arguments-only-once property is important, so |
| + * please be careful when making changes to rcu_assign_pointer() and the |
| + * other macros that it invokes. |
| + */ |
| +#define rcu_assign_pointer(p, v) \ |
| +({ \ |
| + uintptr_t _r_a_p__v = (uintptr_t)(v); \ |
| + \ |
| + if (__builtin_constant_p(v) && (_r_a_p__v) == (uintptr_t)NULL) \ |
| + WRITE_ONCE((p), (typeof(p))(_r_a_p__v)); \ |
| + else \ |
| + smp_store_release(&p, RCU_INITIALIZER((typeof(p))_r_a_p__v)); \ |
| + _r_a_p__v; \ |
| +}) |
| + |
| +#endif |
| --- a/include/linux/rcupdate.h |
| +++ b/include/linux/rcupdate.h |
| @@ -46,6 +46,7 @@ |
| #include <linux/compiler.h> |
| #include <linux/ktime.h> |
| #include <linux/irqflags.h> |
| +#include <linux/rcu_assign_pointer.h> |
| |
| #include <asm/barrier.h> |
| |
| @@ -628,54 +629,6 @@ static inline void rcu_preempt_sleep_che |
| }) |
| |
| /** |
| - * RCU_INITIALIZER() - statically initialize an RCU-protected global variable |
| - * @v: The value to statically initialize with. |
| - */ |
| -#define RCU_INITIALIZER(v) (typeof(*(v)) __force __rcu *)(v) |
| - |
| -/** |
| - * rcu_assign_pointer() - assign to RCU-protected pointer |
| - * @p: pointer to assign to |
| - * @v: value to assign (publish) |
| - * |
| - * Assigns the specified value to the specified RCU-protected |
| - * pointer, ensuring that any concurrent RCU readers will see |
| - * any prior initialization. |
| - * |
| - * Inserts memory barriers on architectures that require them |
| - * (which is most of them), and also prevents the compiler from |
| - * reordering the code that initializes the structure after the pointer |
| - * assignment. More importantly, this call documents which pointers |
| - * will be dereferenced by RCU read-side code. |
| - * |
| - * In some special cases, you may use RCU_INIT_POINTER() instead |
| - * of rcu_assign_pointer(). RCU_INIT_POINTER() is a bit faster due |
| - * to the fact that it does not constrain either the CPU or the compiler. |
| - * That said, using RCU_INIT_POINTER() when you should have used |
| - * rcu_assign_pointer() is a very bad thing that results in |
| - * impossible-to-diagnose memory corruption. So please be careful. |
| - * See the RCU_INIT_POINTER() comment header for details. |
| - * |
| - * Note that rcu_assign_pointer() evaluates each of its arguments only |
| - * once, appearances notwithstanding. One of the "extra" evaluations |
| - * is in typeof() and the other visible only to sparse (__CHECKER__), |
| - * neither of which actually execute the argument. As with most cpp |
| - * macros, this execute-arguments-only-once property is important, so |
| - * please be careful when making changes to rcu_assign_pointer() and the |
| - * other macros that it invokes. |
| - */ |
| -#define rcu_assign_pointer(p, v) \ |
| -({ \ |
| - uintptr_t _r_a_p__v = (uintptr_t)(v); \ |
| - \ |
| - if (__builtin_constant_p(v) && (_r_a_p__v) == (uintptr_t)NULL) \ |
| - WRITE_ONCE((p), (typeof(p))(_r_a_p__v)); \ |
| - else \ |
| - smp_store_release(&p, RCU_INITIALIZER((typeof(p))_r_a_p__v)); \ |
| - _r_a_p__v; \ |
| -}) |
| - |
| -/** |
| * rcu_access_pointer() - fetch RCU pointer with no dereferencing |
| * @p: The pointer to read |
| * |