[PATCH 3.18 32/50] Add hlist_add_tail_rcu() (Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net)

From: Greg Kroah-Hartman
Date: Mon Apr 01 2019 - 13:38:22 EST


3.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: David S. Miller <davem@xxxxxxxxxxxxx>

commit 1602f49b58abcb0d34a5f0a29d68e7c1769547aa upstream.

[This commit was a merge, but it added hlist_add_tail_rcu(), which is what we
need in this stable tree, so I've changed the subject to be more descriptive
- gregkh]

Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
include/linux/rculist.h | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)

--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -405,6 +405,42 @@ static inline void hlist_add_head_rcu(st
}

/**
+ * hlist_add_tail_rcu
+ * @n: the element to add to the hash list.
+ * @h: the list to add to.
+ *
+ * Description:
+ * Adds the specified element to the specified hlist,
+ * while permitting racing traversals.
+ *
+ * The caller must take whatever precautions are necessary
+ * (such as holding appropriate locks) to avoid racing
+ * with another list-mutation primitive, such as hlist_add_head_rcu()
+ * or hlist_del_rcu(), running on this same list.
+ * However, it is perfectly legal to run concurrently with
+ * the _rcu list-traversal primitives, such as
+ * hlist_for_each_entry_rcu(), used to prevent memory-consistency
+ * problems on Alpha CPUs. Regardless of the type of CPU, the
+ * list-traversal primitive must be guarded by rcu_read_lock().
+ */
+static inline void hlist_add_tail_rcu(struct hlist_node *n,
+ struct hlist_head *h)
+{
+ struct hlist_node *i, *last = NULL;
+
+ for (i = hlist_first_rcu(h); i; i = hlist_next_rcu(i))
+ last = i;
+
+ if (last) {
+ n->next = last->next;
+ n->pprev = &last->next;
+ rcu_assign_pointer(hlist_next_rcu(last), n);
+ } else {
+ hlist_add_head_rcu(n, h);
+ }
+}
+
+/**
* hlist_add_before_rcu
* @n: the new element to add to the hash list.
* @next: the existing element to add the new element before.