[PATCH] docs: fix bug in "Krefs and RCU" example

From: Dmitry Mastykin
Date: Tue Mar 19 2024 - 03:27:31 EST


There is a problem in "Krefs and RCU" example, that may cause a crash.
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, like in list_first_or_null_rcu() macro.

Signed-off-by: Dmitry Mastykin <dmastykin@xxxxxxxxxxxxx>
---
Documentation/core-api/kref.rst | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/Documentation/core-api/kref.rst b/Documentation/core-api/kref.rst
index c61eea6f1bf2..022bb1d1b968 100644
--- a/Documentation/core-api/kref.rst
+++ b/Documentation/core-api/kref.rst
@@ -290,13 +290,11 @@ locking for lookups in the above example::

static struct my_data *get_entry_rcu()
{
- struct my_data *entry = NULL;
+ struct my_data *entry;
rcu_read_lock();
- if (!list_empty(&q)) {
- entry = container_of(q.next, struct my_data, link);
- if (!kref_get_unless_zero(&entry->refcount))
- entry = NULL;
- }
+ entry = list_first_or_null_rcu(&q, struct my_data, link);
+ if (entry && !kref_get_unless_zero(&entry->refcount))
+ entry = NULL;
rcu_read_unlock();
return entry;
}
--
2.30.2