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

Commit 1658d35e authored by Paul E. McKenney's avatar Paul E. McKenney
Browse files

list: Use READ_ONCE() when testing for empty lists



Most of the list-empty-check macros (list_empty(), hlist_empty(),
hlist_bl_empty(), hlist_nulls_empty(), and hlist_nulls_empty()) use
an unadorned load to check the list header.  Given that these macros
are sometimes invoked without the protection of a lock, this is
not sufficient.  This commit therefore adds READ_ONCE() calls to
them.  This commit does not touch llist_empty() because it already
has the needed ACCESS_ONCE().

Reported-by: default avatarDmitry Vyukov <dvyukov@google.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
parent 1c97be67
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -186,7 +186,7 @@ static inline int list_is_last(const struct list_head *list,
 */
 */
static inline int list_empty(const struct list_head *head)
static inline int list_empty(const struct list_head *head)
{
{
	return head->next == head;
	return READ_ONCE(head->next) == head;
}
}


/**
/**
@@ -608,7 +608,7 @@ static inline int hlist_unhashed(const struct hlist_node *h)


static inline int hlist_empty(const struct hlist_head *h)
static inline int hlist_empty(const struct hlist_head *h)
{
{
	return !h->first;
	return !READ_ONCE(h->first);
}
}


static inline void __hlist_del(struct hlist_node *n)
static inline void __hlist_del(struct hlist_node *n)
+1 −1
Original line number Original line Diff line number Diff line
@@ -70,7 +70,7 @@ static inline void hlist_bl_set_first(struct hlist_bl_head *h,


static inline int hlist_bl_empty(const struct hlist_bl_head *h)
static inline int hlist_bl_empty(const struct hlist_bl_head *h)
{
{
	return !((unsigned long)h->first & ~LIST_BL_LOCKMASK);
	return !((unsigned long)READ_ONCE(h->first) & ~LIST_BL_LOCKMASK);
}
}


static inline void hlist_bl_add_head(struct hlist_bl_node *n,
static inline void hlist_bl_add_head(struct hlist_bl_node *n,
+1 −1
Original line number Original line Diff line number Diff line
@@ -57,7 +57,7 @@ static inline int hlist_nulls_unhashed(const struct hlist_nulls_node *h)


static inline int hlist_nulls_empty(const struct hlist_nulls_head *h)
static inline int hlist_nulls_empty(const struct hlist_nulls_head *h)
{
{
	return is_a_nulls(h->first);
	return is_a_nulls(READ_ONCE(h->first));
}
}


static inline void hlist_nulls_add_head(struct hlist_nulls_node *n,
static inline void hlist_nulls_add_head(struct hlist_nulls_node *n,