Commit 559f9badd11ddf399f88b18b4c0f110fd511ae53
Committed by
Paul E. McKenney
1 parent
66f75a5d02
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
rcu: List-debug variants of rcu list routines.
* Make __list_add_rcu check the next->prev and prev->next pointers just like __list_add does. * Make list_del_rcu use __list_del_entry, which does the same checking at deletion time. Has been running for a week here without anything being tripped up, but it seems worth adding for completeness just in case something ever does corrupt those lists. Signed-off-by: Dave Jones <davej@redhat.com> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Showing 2 changed files with 28 additions and 1 deletions Side-by-side Diff
include/linux/rculist.h
... | ... | @@ -30,6 +30,7 @@ |
30 | 30 | * This is only for internal list manipulation where we know |
31 | 31 | * the prev/next entries already! |
32 | 32 | */ |
33 | +#ifndef CONFIG_DEBUG_LIST | |
33 | 34 | static inline void __list_add_rcu(struct list_head *new, |
34 | 35 | struct list_head *prev, struct list_head *next) |
35 | 36 | { |
... | ... | @@ -38,6 +39,10 @@ |
38 | 39 | rcu_assign_pointer(list_next_rcu(prev), new); |
39 | 40 | next->prev = new; |
40 | 41 | } |
42 | +#else | |
43 | +extern void __list_add_rcu(struct list_head *new, | |
44 | + struct list_head *prev, struct list_head *next); | |
45 | +#endif | |
41 | 46 | |
42 | 47 | /** |
43 | 48 | * list_add_rcu - add a new entry to rcu-protected list |
... | ... | @@ -108,7 +113,7 @@ |
108 | 113 | */ |
109 | 114 | static inline void list_del_rcu(struct list_head *entry) |
110 | 115 | { |
111 | - __list_del(entry->prev, entry->next); | |
116 | + __list_del_entry(entry); | |
112 | 117 | entry->prev = LIST_POISON2; |
113 | 118 | } |
114 | 119 |
lib/list_debug.c
... | ... | @@ -10,6 +10,7 @@ |
10 | 10 | #include <linux/list.h> |
11 | 11 | #include <linux/bug.h> |
12 | 12 | #include <linux/kernel.h> |
13 | +#include <linux/rculist.h> | |
13 | 14 | |
14 | 15 | /* |
15 | 16 | * Insert a new entry between two known consecutive entries. |
... | ... | @@ -75,4 +76,25 @@ |
75 | 76 | entry->prev = LIST_POISON2; |
76 | 77 | } |
77 | 78 | EXPORT_SYMBOL(list_del); |
79 | + | |
80 | +/* | |
81 | + * RCU variants. | |
82 | + */ | |
83 | +void __list_add_rcu(struct list_head *new, | |
84 | + struct list_head *prev, struct list_head *next) | |
85 | +{ | |
86 | + WARN(next->prev != prev, | |
87 | + "list_add_rcu corruption. next->prev should be " | |
88 | + "prev (%p), but was %p. (next=%p).\n", | |
89 | + prev, next->prev, next); | |
90 | + WARN(prev->next != next, | |
91 | + "list_add_rcu corruption. prev->next should be " | |
92 | + "next (%p), but was %p. (prev=%p).\n", | |
93 | + next, prev->next, prev); | |
94 | + new->next = next; | |
95 | + new->prev = prev; | |
96 | + rcu_assign_pointer(list_next_rcu(prev), new); | |
97 | + next->prev = new; | |
98 | +} | |
99 | +EXPORT_SYMBOL(__list_add_rcu); |