|
@@ -10,6 +10,7 @@
|
|
|
#include <linux/list.h>
|
|
|
#include <linux/bug.h>
|
|
|
#include <linux/kernel.h>
|
|
|
+#include <linux/rculist.h>
|
|
|
|
|
|
/*
|
|
|
* Insert a new entry between two known consecutive entries.
|
|
@@ -75,3 +76,24 @@ void list_del(struct list_head *entry)
|
|
|
entry->prev = LIST_POISON2;
|
|
|
}
|
|
|
EXPORT_SYMBOL(list_del);
|
|
|
+
|
|
|
+/*
|
|
|
+ * RCU variants.
|
|
|
+ */
|
|
|
+void __list_add_rcu(struct list_head *new,
|
|
|
+ struct list_head *prev, struct list_head *next)
|
|
|
+{
|
|
|
+ WARN(next->prev != prev,
|
|
|
+ "list_add_rcu corruption. next->prev should be "
|
|
|
+ "prev (%p), but was %p. (next=%p).\n",
|
|
|
+ prev, next->prev, next);
|
|
|
+ WARN(prev->next != next,
|
|
|
+ "list_add_rcu corruption. prev->next should be "
|
|
|
+ "next (%p), but was %p. (prev=%p).\n",
|
|
|
+ next, prev->next, prev);
|
|
|
+ new->next = next;
|
|
|
+ new->prev = prev;
|
|
|
+ rcu_assign_pointer(list_next_rcu(prev), new);
|
|
|
+ next->prev = new;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(__list_add_rcu);
|