diff options
-rw-r--r-- | include/linux/rculist.h | 7 | ||||
-rw-r--r-- | lib/list_debug.c | 22 |
2 files changed, 28 insertions, 1 deletions
diff --git a/include/linux/rculist.h b/include/linux/rculist.h index d079290843a9..a20c05096231 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h | |||
@@ -30,6 +30,7 @@ | |||
30 | * This is only for internal list manipulation where we know | 30 | * This is only for internal list manipulation where we know |
31 | * the prev/next entries already! | 31 | * the prev/next entries already! |
32 | */ | 32 | */ |
33 | #ifndef CONFIG_DEBUG_LIST | ||
33 | static inline void __list_add_rcu(struct list_head *new, | 34 | static inline void __list_add_rcu(struct list_head *new, |
34 | struct list_head *prev, struct list_head *next) | 35 | struct list_head *prev, struct list_head *next) |
35 | { | 36 | { |
@@ -38,6 +39,10 @@ static inline void __list_add_rcu(struct list_head *new, | |||
38 | rcu_assign_pointer(list_next_rcu(prev), new); | 39 | rcu_assign_pointer(list_next_rcu(prev), new); |
39 | next->prev = new; | 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 | * list_add_rcu - add a new entry to rcu-protected list | 48 | * list_add_rcu - add a new entry to rcu-protected list |
@@ -108,7 +113,7 @@ static inline void list_add_tail_rcu(struct list_head *new, | |||
108 | */ | 113 | */ |
109 | static inline void list_del_rcu(struct list_head *entry) | 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 | entry->prev = LIST_POISON2; | 117 | entry->prev = LIST_POISON2; |
113 | } | 118 | } |
114 | 119 | ||
diff --git a/lib/list_debug.c b/lib/list_debug.c index 982b850d4e7a..3810b481f940 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. |
@@ -75,3 +76,24 @@ void list_del(struct list_head *entry) | |||
75 | entry->prev = LIST_POISON2; | 76 | entry->prev = LIST_POISON2; |
76 | } | 77 | } |
77 | EXPORT_SYMBOL(list_del); | 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); | ||