Hello all, It seems there is a problem in "Krefs and RCU" example, that may cause a crash. I marked the place between two problem lines with "problem is here" comment. If list_del_rcu() will be called between these lines, and list will become empty, then q.next will not point to a valid struct my_data. entry->refcount will also be invalid. Instead, q.next must be read first, and then compared with q to check list's emptiness (for example like in list_for_each_entry_rcu macro). Signed-off-by: Dmitry Mastykin <dmastykin@xxxxxxxxxxxxx> diff --git a/Documentation/core-api/kref.rst b/Documentation/core-api/kref.rst index c61eea6f1bf2..b76d71d9c9a0 100644 --- a/Documentation/core-api/kref.rst +++ b/Documentation/core-api/kref.rst @@ -274,44 +274,45 @@ return value. If you are sure (by already having a valid pointer) that kref_get_unless_zero() will return true, then use kref_get() instead. Krefs and RCU ============= The function kref_get_unless_zero also makes it possible to use rcu locking for lookups in the above example:: struct my_data { struct rcu_head rhead; . struct kref refcount; . . }; static struct my_data *get_entry_rcu() { struct my_data *entry = NULL; rcu_read_lock(); if (!list_empty(&q)) { + // problem is here entry = container_of(q.next, struct my_data, link); if (!kref_get_unless_zero(&entry->refcount)) entry = NULL; } rcu_read_unlock(); return entry; } static void release_entry_rcu(struct kref *ref) { struct my_data *entry = container_of(ref, struct my_data, refcount); mutex_lock(&mutex); list_del_rcu(&entry->link); mutex_unlock(&mutex); kfree_rcu(entry, rhead); } static void put_entry(struct my_data *entry) { kref_put(&entry->refcount, release_entry_rcu); }