为什么list_add_rcu只保护"prev->next"?
Why does list_add_rcu only protect "prev->next"?
以下是include/linux/rculist.h中__list_add_rcu
的实现:
static inline void __list_add_rcu(struct list_head *new,
struct list_head *prev, struct list_head *next)
{
new->next = next;
new->prev = prev;
rcu_assign_pointer(list_next_rcu(prev), new);
next->prev = new;
}
在函数体内,rcu-lock保护prev->next
的更新,但不保护next->prev
。为什么?我在这里错过了什么明显的东西吗?
RCU-lock 无法保证双向遍历链表的正确性。
简而言之,这样的保证需要"protect"两个指针(next->prev
和prev->next
)同时。但是RCU-section不是一个exclusive section,所以两个指针的值可能不一致
正因为如此,RCU 只保证正向列表遍历的正确性。为此,仅保护 prev->next
.
就足够了
提示:虽然存在用于反向列表遍历的宏(例如list_for_each_entry_reverse
),但此类宏没有RCU counterpairs。这是因为RCU不支持这种遍历类型
以下是include/linux/rculist.h中__list_add_rcu
的实现:
static inline void __list_add_rcu(struct list_head *new,
struct list_head *prev, struct list_head *next)
{
new->next = next;
new->prev = prev;
rcu_assign_pointer(list_next_rcu(prev), new);
next->prev = new;
}
在函数体内,rcu-lock保护prev->next
的更新,但不保护next->prev
。为什么?我在这里错过了什么明显的东西吗?
RCU-lock 无法保证双向遍历链表的正确性。
简而言之,这样的保证需要"protect"两个指针(next->prev
和prev->next
)同时。但是RCU-section不是一个exclusive section,所以两个指针的值可能不一致
正因为如此,RCU 只保证正向列表遍历的正确性。为此,仅保护 prev->next
.
提示:虽然存在用于反向列表遍历的宏(例如list_for_each_entry_reverse
),但此类宏没有RCU counterpairs。这是因为RCU不支持这种遍历类型