From: Michel Machado <michel@digirati.com.br>
To: Dipankar Sarma <dipankar@in.ibm.com>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH 1/1] rculist: Made list_first_entry_rcu usable
Date: Mon, 02 Apr 2012 21:42:34 -0400 [thread overview]
Message-ID: <1333417354.2412.7.camel@Thor> (raw)
The macro list_first_entry_rcu assumed that the passed list is not empty
as its counterpart list_first_entry does. However, one can test that a
list is not empty with list_empty before calling list_first_entry,
whereas neither exists list_empty_rcu, nor is advisable to add it as the
example below shows.
Assuming that list_empty_rcu is available, one could write the following
snippet:
if (!list_empty_rcu(mylist)) {
struct foo *bar = list_first_entry_rcu(mylist, struct foo,
list_member);
do_something(bar);
}
The problem with this snippet is the following racing condition: the
list may not be empty when list_empty_rcu checks it, but it may be when
list_first_entry_rcu rereads the ->next pointer.
This patch cannot break any upstream code because list_first_entry_rcu
is not being used anywhere in the kernel (tested with grep(1)), and
external code that uses it is probably broken already.
Signed-off-by: Michel Machado <michel@digirati.com.br>
CC: Dipankar Sarma <dipankar@in.ibm.com>
CC: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
---
Please CC my e-mail address while replying this message because I don't
subscribe this mailing list due to its high volume; thanks.
diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index d079290..866d3ec 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -233,13 +233,16 @@ static inline void list_splice_init_rcu(struct
list_head *list,
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
- * Note, that list is expected to be not empty.
+ * Note that if the list is empty, it returns NULL.
*
* This primitive may safely run concurrently with the _rcu
list-mutation
* primitives such as list_add_rcu() as long as it's guarded by
rcu_read_lock().
*/
#define list_first_entry_rcu(ptr, type, member) \
- list_entry_rcu((ptr)->next, type, member)
+ ({struct list_head *__ptr = ptr; \
+ struct list_head __rcu *__next = list_next_rcu(__ptr); \
+ likely(__ptr != __next) ? container_of(__next, type, member) : NULL;
\
+ })
/**
* list_for_each_entry_rcu - iterate over rcu list of given type
next reply other threads:[~2012-04-03 1:42 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-03 1:42 Michel Machado [this message]
2012-04-09 21:24 ` [PATCH 1/1] rculist: Made list_first_entry_rcu usable Paul E. McKenney
2012-04-09 22:08 ` Michel Machado
2012-04-09 22:22 ` Paul E. McKenney
2012-04-09 22:42 ` Michel Machado
2012-04-09 23:11 ` Paul E. McKenney
-- strict thread matches above, loose matches on Subject: below --
2012-03-26 1:08 Michel Machado
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1333417354.2412.7.camel@Thor \
--to=michel@digirati.com.br \
--cc=dipankar@in.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=paulmck@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.