Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c97be67 authored by Paul E. McKenney's avatar Paul E. McKenney
Browse files

list: Use WRITE_ONCE() when adding to lists and hlists



Code that does lockless emptiness testing of non-RCU lists is relying
on the list-addition code to write the list head's ->next pointer
atomically.  This commit therefore adds WRITE_ONCE() to list-addition
pointer stores that could affect the head's ->next pointer.

Reported-by: default avatarDmitry Vyukov <dvyukov@google.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
parent 6cf10081
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -42,7 +42,7 @@ static inline void __list_add(struct list_head *new,
	next->prev = new;
	next->prev = new;
	new->next = next;
	new->next = next;
	new->prev = prev;
	new->prev = prev;
	prev->next = new;
	WRITE_ONCE(prev->next, new);
}
}
#else
#else
extern void __list_add(struct list_head *new,
extern void __list_add(struct list_head *new,
@@ -642,7 +642,7 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
	n->next = first;
	n->next = first;
	if (first)
	if (first)
		first->pprev = &n->next;
		first->pprev = &n->next;
	h->first = n;
	WRITE_ONCE(h->first, n);
	n->pprev = &h->first;
	n->pprev = &h->first;
}
}


@@ -653,14 +653,14 @@ static inline void hlist_add_before(struct hlist_node *n,
	n->pprev = next->pprev;
	n->pprev = next->pprev;
	n->next = next;
	n->next = next;
	next->pprev = &n->next;
	next->pprev = &n->next;
	*(n->pprev) = n;
	WRITE_ONCE(*(n->pprev), n);
}
}


static inline void hlist_add_behind(struct hlist_node *n,
static inline void hlist_add_behind(struct hlist_node *n,
				    struct hlist_node *prev)
				    struct hlist_node *prev)
{
{
	n->next = prev->next;
	n->next = prev->next;
	prev->next = n;
	WRITE_ONCE(prev->next, n);
	n->pprev = &prev->next;
	n->pprev = &prev->next;


	if (n->next)
	if (n->next)
+1 −1
Original line number Original line Diff line number Diff line
@@ -37,7 +37,7 @@ void __list_add(struct list_head *new,
	next->prev = new;
	next->prev = new;
	new->next = next;
	new->next = next;
	new->prev = prev;
	new->prev = prev;
	prev->next = new;
	WRITE_ONCE(prev->next, new);
}
}
EXPORT_SYMBOL(__list_add);
EXPORT_SYMBOL(__list_add);