rcu: add an rcu_dereference_index_check()
The sparse RCU-pointer checking relies on type magic that dereferences the pointer in question. This does not work if the pointer is in fact an array index. This commit therefore supplies a new RCU API that omits the sparse checking to continue to support rcu_dereference() on integers. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
This commit is contained in:
@@ -566,4 +566,37 @@ static inline void debug_rcu_head_unqueue(struct rcu_head *head)
|
|||||||
}
|
}
|
||||||
#endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_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 */
|
||||||
|
Reference in New Issue
Block a user