diff options
Diffstat (limited to 'kernel/rcu/tiny.c')
| -rw-r--r-- | kernel/rcu/tiny.c | 25 | 
1 files changed, 21 insertions, 4 deletions
| diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c index 340b3f8b090d..f0561ee16b9c 100644 --- a/kernel/rcu/tiny.c +++ b/kernel/rcu/tiny.c @@ -58,7 +58,7 @@ void rcu_qs(void)  		rcu_ctrlblk.donetail = rcu_ctrlblk.curtail;  		raise_softirq_irqoff(RCU_SOFTIRQ);  	} -	WRITE_ONCE(rcu_ctrlblk.gp_seq, rcu_ctrlblk.gp_seq + 1); +	WRITE_ONCE(rcu_ctrlblk.gp_seq, rcu_ctrlblk.gp_seq + 2);  	local_irq_restore(flags);  } @@ -139,8 +139,10 @@ static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused  /*   * Wait for a grace period to elapse.  But it is illegal to invoke   * synchronize_rcu() from within an RCU read-side critical section. - * Therefore, any legal call to synchronize_rcu() is a quiescent - * state, and so on a UP system, synchronize_rcu() need do nothing. + * Therefore, any legal call to synchronize_rcu() is a quiescent state, + * and so on a UP system, synchronize_rcu() need do nothing, other than + * let the polled APIs know that another grace period elapsed. + *   * (But Lai Jiangshan points out the benefits of doing might_sleep()   * to reduce latency.)   * @@ -152,6 +154,7 @@ void synchronize_rcu(void)  			 lock_is_held(&rcu_lock_map) ||  			 lock_is_held(&rcu_sched_lock_map),  			 "Illegal synchronize_rcu() in RCU read-side critical section"); +	WRITE_ONCE(rcu_ctrlblk.gp_seq, rcu_ctrlblk.gp_seq + 2);  }  EXPORT_SYMBOL_GPL(synchronize_rcu); @@ -213,10 +216,24 @@ EXPORT_SYMBOL_GPL(start_poll_synchronize_rcu);   */  bool poll_state_synchronize_rcu(unsigned long oldstate)  { -	return READ_ONCE(rcu_ctrlblk.gp_seq) != oldstate; +	return oldstate == RCU_GET_STATE_COMPLETED || READ_ONCE(rcu_ctrlblk.gp_seq) != oldstate;  }  EXPORT_SYMBOL_GPL(poll_state_synchronize_rcu); +#ifdef CONFIG_KASAN_GENERIC +void kvfree_call_rcu(struct rcu_head *head, rcu_callback_t func) +{ +	if (head) { +		void *ptr = (void *) head - (unsigned long) func; + +		kasan_record_aux_stack_noalloc(ptr); +	} + +	__kvfree_call_rcu(head, func); +} +EXPORT_SYMBOL_GPL(kvfree_call_rcu); +#endif +  void __init rcu_init(void)  {  	open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); | 
