forked from mirrors/linux
		
	rcu: Make __kfree_rcu() less dependent on compiler choices
Currently, __kfree_rcu() is implemented as an inline function, and contains a BUILD_BUG_ON() that malfunctions if __kfree_rcu() is compiled as an out-of-line function. Unfortunately, there are compiler settings (e.g., -O0) that can result in __kfree_rcu() being compiled out of line, resulting in annoying build breakage. This commit therefore converts both __kfree_rcu() and __is_kfree_rcu_offset() from inline functions to macros to prevent such misbehavior on the part of the compiler. Signed-off-by: Jan Engelhardt <jengelh@medozas.de> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
This commit is contained in:
		
							parent
							
								
									c9336643e1
								
							
						
					
					
						commit
						d8169d4c36
					
				
					 1 changed files with 18 additions and 0 deletions
				
			
		| 
						 | 
					@ -922,6 +922,21 @@ void __kfree_rcu(struct rcu_head *head, unsigned long offset)
 | 
				
			||||||
	kfree_call_rcu(head, (rcu_callback)offset);
 | 
						kfree_call_rcu(head, (rcu_callback)offset);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Does the specified offset indicate that the corresponding rcu_head
 | 
				
			||||||
 | 
					 * structure can be handled by kfree_rcu()?
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define __is_kfree_rcu_offset(offset) ((offset) < 4096)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Helper macro for kfree_rcu() to prevent argument-expansion eyestrain.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define __kfree_rcu(head, offset) \
 | 
				
			||||||
 | 
						do { \
 | 
				
			||||||
 | 
							BUILD_BUG_ON(!__is_kfree_rcu_offset(offset)); \
 | 
				
			||||||
 | 
							call_rcu(head, (void (*)(struct rcu_head *))(unsigned long)(offset)); \
 | 
				
			||||||
 | 
						} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * kfree_rcu() - kfree an object after a grace period.
 | 
					 * kfree_rcu() - kfree an object after a grace period.
 | 
				
			||||||
 * @ptr:	pointer to kfree
 | 
					 * @ptr:	pointer to kfree
 | 
				
			||||||
| 
						 | 
					@ -944,6 +959,9 @@ void __kfree_rcu(struct rcu_head *head, unsigned long offset)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Note that the allowable offset might decrease in the future, for example,
 | 
					 * Note that the allowable offset might decrease in the future, for example,
 | 
				
			||||||
 * to allow something like kmem_cache_free_rcu().
 | 
					 * to allow something like kmem_cache_free_rcu().
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The BUILD_BUG_ON check must not involve any function calls, hence the
 | 
				
			||||||
 | 
					 * checks are done in macros here.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define kfree_rcu(ptr, rcu_head)					\
 | 
					#define kfree_rcu(ptr, rcu_head)					\
 | 
				
			||||||
	__kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head))
 | 
						__kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue