[PATCH] list: add missing rcu_dereference on first element
authorHerbert Xu <herbert@gondor.apana.org.au>
Mon, 17 Oct 2005 03:29:20 +0000 (20:29 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 17 Oct 2005 15:59:10 +0000 (08:59 -0700)
commitb24d18aa743dad0c42918157c5d717686269d3a8
treeceade1641a1806c5f3db2f4b344fe9070b488bad
parent3d80636a0d5f056ffc26472d05b6027a7a9f6e1c
[PATCH] list: add missing rcu_dereference on first element

It seems that all the list_*_rcu primitives are missing a memory barrier
on the very first dereference.  For example,

#define list_for_each_rcu(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = rcu_dereference(pos->next))

It will go something like:

pos = (head)->next

prefetch(pos->next)

pos != (head)

do stuff

We're missing a barrier here.

pos = rcu_dereference(pos->next)

fetch pos->next

barrier given by rcu_dereference(pos->next)

store pos

Without the missing barrier, the pos->next value may turn out to be stale.
In fact, if "do stuff" were also dereferencing pos and relying on
list_for_each_rcu to provide the barrier then it may also break.

So here is a patch to make sure that we have a barrier for the first
element in the list.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: "Paul E. McKenney" <paulmck@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
include/linux/list.h