Почему list_add_rcu защищает только "prev->next"?
Ниже приводится реализация __list_add_rcu
в include / linux / rculist.h:
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
, Зачем? Я что-то упустил здесь очевидное?
1 ответ
RCU-lock не может гарантировать правильность списка перемещения в обоих направлениях.
Короче, такая гарантия потребовала бы "защиты" двух указателей (next->prev
а также prev->next
) сразу. Но RCU-секция не является эксклюзивной секцией, поэтому два указателя могут иметь значения, несовместимые между собой.
Из-за этого RCU гарантирует корректность только для обхода списка вперед. Для этого достаточно защитить только prev->next
,
Подсказка: хотя существуют макросы для обратного просмотра списка (например, list_for_each_entry_reverse
), такие макросы не имеют аналогов RCU. Это просто потому, что RCU не поддерживает такой тип обхода.