History

rculist: Add brackets around cond argument in __list_check_rcu macro

Passing a complex lockdep condition to __list_check_rcu results in false positive lockdep splat due to incorrect expression evaluation. For example, a lockdep check condition `cond1 || cond2` is evaluated as `!cond1 || cond2 && !rcu_read_lock_any_held()` which, according to operator precedence, evaluates to `!cond1 || (cond2 && !rcu_read_lock_any_held())`. This would result in a lockdep splat when cond1 is false and cond2 is true which is logically incorrect.

Amol Grover committed 6 years ago

Commit 4dfd5cd1 parent aa24f931 file · +2 −2Browse files

Showing the changes to include/linux (1 of 1 file). Show all

Unified · Split

include/linux/rculist.h+2−2
@@ -60,9 +60,9 @@ static inline void INIT_LIST_HEAD_RCU(struct list_head *list) · 59 unmodified lines
60#define __list_check_rcu(dummy, cond, extra...) \60#define __list_check_rcu(dummy, cond, extra...) \
61 ({ \61 ({ \
62 check_arg_count_one(extra); \62 check_arg_count_one(extra); \
63 RCU_LOCKDEP_WARN(!cond && !rcu_read_lock_any_held(), \63 RCU_LOCKDEP_WARN(!(cond) && !rcu_read_lock_any_held(), \
64 "RCU-list traversed in non-reader section!"); \64 "RCU-list traversed in non-reader section!"); \
65 })65 })
66#else66#else
67#define __list_check_rcu(dummy, cond, extra...) \67#define __list_check_rcu(dummy, cond, extra...) \
68 ({ check_arg_count_one(extra); })68 ({ check_arg_count_one(extra); })