diff options
Diffstat (limited to 'kernel/rcu/tiny.c')
| -rw-r--r-- | kernel/rcu/tiny.c | 27 | 
1 files changed, 26 insertions, 1 deletions
diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c index f0561ee16b9c..a33a8d4942c3 100644 --- a/kernel/rcu/tiny.c +++ b/kernel/rcu/tiny.c @@ -158,6 +158,10 @@ void synchronize_rcu(void)  }  EXPORT_SYMBOL_GPL(synchronize_rcu); +static void tiny_rcu_leak_callback(struct rcu_head *rhp) +{ +} +  /*   * Post an RCU callback to be invoked after the end of an RCU grace   * period.  But since we have but one CPU, that would be after any @@ -165,9 +169,20 @@ EXPORT_SYMBOL_GPL(synchronize_rcu);   */  void call_rcu(struct rcu_head *head, rcu_callback_t func)  { +	static atomic_t doublefrees;  	unsigned long flags; -	debug_rcu_head_queue(head); +	if (debug_rcu_head_queue(head)) { +		if (atomic_inc_return(&doublefrees) < 4) { +			pr_err("%s(): Double-freed CB %p->%pS()!!!  ", __func__, head, head->func); +			mem_dump_obj(head); +		} + +		if (!__is_kvfree_rcu_offset((unsigned long)head->func)) +			WRITE_ONCE(head->func, tiny_rcu_leak_callback); +		return; +	} +  	head->func = func;  	head->next = NULL; @@ -184,6 +199,16 @@ void call_rcu(struct rcu_head *head, rcu_callback_t func)  EXPORT_SYMBOL_GPL(call_rcu);  /* + * Store a grace-period-counter "cookie".  For more information, + * see the Tree RCU header comment. + */ +void get_completed_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp) +{ +	rgosp->rgos_norm = RCU_GET_STATE_COMPLETED; +} +EXPORT_SYMBOL_GPL(get_completed_synchronize_rcu_full); + +/*   * Return a grace-period-counter "cookie".  For more information,   * see the Tree RCU header comment.   */  |