mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-11-01 09:13:37 +00:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									66f75a5d02
								
							
						
					
					
						commit
						559f9badd1
					
				
					 2 changed files with 28 additions and 1 deletions
				
			
		| 
						 | 
					@ -30,6 +30,7 @@
 | 
				
			||||||
 * This is only for internal list manipulation where we know
 | 
					 * This is only for internal list manipulation where we know
 | 
				
			||||||
 * the prev/next entries already!
 | 
					 * the prev/next entries already!
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef CONFIG_DEBUG_LIST
 | 
				
			||||||
static inline void __list_add_rcu(struct list_head *new,
 | 
					static inline void __list_add_rcu(struct list_head *new,
 | 
				
			||||||
		struct list_head *prev, struct list_head *next)
 | 
							struct list_head *prev, struct list_head *next)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -38,6 +39,10 @@ static inline void __list_add_rcu(struct list_head *new,
 | 
				
			||||||
	rcu_assign_pointer(list_next_rcu(prev), new);
 | 
						rcu_assign_pointer(list_next_rcu(prev), new);
 | 
				
			||||||
	next->prev = new;
 | 
						next->prev = new;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					extern void __list_add_rcu(struct list_head *new,
 | 
				
			||||||
 | 
							struct list_head *prev, struct list_head *next);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * list_add_rcu - add a new entry to rcu-protected list
 | 
					 * 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,
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static inline void list_del_rcu(struct list_head *entry)
 | 
					static inline void list_del_rcu(struct list_head *entry)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	__list_del(entry->prev, entry->next);
 | 
						__list_del_entry(entry);
 | 
				
			||||||
	entry->prev = LIST_POISON2;
 | 
						entry->prev = LIST_POISON2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,7 @@
 | 
				
			||||||
#include <linux/list.h>
 | 
					#include <linux/list.h>
 | 
				
			||||||
#include <linux/bug.h>
 | 
					#include <linux/bug.h>
 | 
				
			||||||
#include <linux/kernel.h>
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
 | 
					#include <linux/rculist.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Insert a new entry between two known consecutive entries.
 | 
					 * Insert a new entry between two known consecutive entries.
 | 
				
			||||||
| 
						 | 
					@ -75,3 +76,24 @@ void list_del(struct list_head *entry)
 | 
				
			||||||
	entry->prev = LIST_POISON2;
 | 
						entry->prev = LIST_POISON2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(list_del);
 | 
					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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue