diff options
Diffstat (limited to 'lib/list_debug.c')
-rw-r--r-- | lib/list_debug.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/list_debug.c b/lib/list_debug.c index 982b850d4e7a..23a5e031cd8b 100644 --- a/lib/list_debug.c +++ b/lib/list_debug.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/list.h> | 10 | #include <linux/list.h> |
11 | #include <linux/bug.h> | 11 | #include <linux/bug.h> |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/rculist.h> | ||
13 | 14 | ||
14 | /* | 15 | /* |
15 | * Insert a new entry between two known consecutive entries. | 16 | * Insert a new entry between two known consecutive entries. |
@@ -30,6 +31,9 @@ void __list_add(struct list_head *new, | |||
30 | "list_add corruption. prev->next should be " | 31 | "list_add corruption. prev->next should be " |
31 | "next (%p), but was %p. (prev=%p).\n", | 32 | "next (%p), but was %p. (prev=%p).\n", |
32 | next, prev->next, prev); | 33 | next, prev->next, prev); |
34 | WARN(new == prev || new == next, | ||
35 | "list_add double add: new=%p, prev=%p, next=%p.\n", | ||
36 | new, prev, next); | ||
33 | next->prev = new; | 37 | next->prev = new; |
34 | new->next = next; | 38 | new->next = next; |
35 | new->prev = prev; | 39 | new->prev = prev; |
@@ -75,3 +79,24 @@ void list_del(struct list_head *entry) | |||
75 | entry->prev = LIST_POISON2; | 79 | entry->prev = LIST_POISON2; |
76 | } | 80 | } |
77 | EXPORT_SYMBOL(list_del); | 81 | EXPORT_SYMBOL(list_del); |
82 | |||
83 | /* | ||
84 | * RCU variants. | ||
85 | */ | ||
86 | void __list_add_rcu(struct list_head *new, | ||
87 | struct list_head *prev, struct list_head *next) | ||
88 | { | ||
89 | WARN(next->prev != prev, | ||
90 | "list_add_rcu corruption. next->prev should be " | ||
91 | "prev (%p), but was %p. (next=%p).\n", | ||
92 | prev, next->prev, next); | ||
93 | WARN(prev->next != next, | ||
94 | "list_add_rcu corruption. prev->next should be " | ||
95 | "next (%p), but was %p. (prev=%p).\n", | ||
96 | next, prev->next, prev); | ||
97 | new->next = next; | ||
98 | new->prev = prev; | ||
99 | rcu_assign_pointer(list_next_rcu(prev), new); | ||
100 | next->prev = new; | ||
101 | } | ||
102 | EXPORT_SYMBOL(__list_add_rcu); | ||