diff options
Diffstat (limited to 'kernel/rcu/srcutree.c')
| -rw-r--r-- | kernel/rcu/srcutree.c | 11 | 
1 files changed, 6 insertions, 5 deletions
diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index 5dffade2d7cd..657e6a7d1c03 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -530,7 +530,7 @@ static void srcu_gp_end(struct srcu_struct *ssp)  	idx = rcu_seq_state(ssp->srcu_gp_seq);  	WARN_ON_ONCE(idx != SRCU_STATE_SCAN2);  	cbdelay = srcu_get_delay(ssp); -	ssp->srcu_last_gp_end = ktime_get_mono_fast_ns(); +	WRITE_ONCE(ssp->srcu_last_gp_end, ktime_get_mono_fast_ns());  	rcu_seq_end(&ssp->srcu_gp_seq);  	gpseq = rcu_seq_current(&ssp->srcu_gp_seq);  	if (ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, gpseq)) @@ -762,6 +762,7 @@ static bool srcu_might_be_idle(struct srcu_struct *ssp)  	unsigned long flags;  	struct srcu_data *sdp;  	unsigned long t; +	unsigned long tlast;  	/* If the local srcu_data structure has callbacks, not idle.  */  	local_irq_save(flags); @@ -780,9 +781,9 @@ static bool srcu_might_be_idle(struct srcu_struct *ssp)  	/* First, see if enough time has passed since the last GP. */  	t = ktime_get_mono_fast_ns(); +	tlast = READ_ONCE(ssp->srcu_last_gp_end);  	if (exp_holdoff == 0 || -	    time_in_range_open(t, ssp->srcu_last_gp_end, -			       ssp->srcu_last_gp_end + exp_holdoff)) +	    time_in_range_open(t, tlast, tlast + exp_holdoff))  		return false; /* Too soon after last GP. */  	/* Next, check for probable idleness. */ @@ -853,7 +854,7 @@ static void __call_srcu(struct srcu_struct *ssp, struct rcu_head *rhp,  	local_irq_save(flags);  	sdp = this_cpu_ptr(ssp->sda);  	spin_lock_rcu_node(sdp); -	rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp, false); +	rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp);  	rcu_segcblist_advance(&sdp->srcu_cblist,  			      rcu_seq_current(&ssp->srcu_gp_seq));  	s = rcu_seq_snap(&ssp->srcu_gp_seq); @@ -1052,7 +1053,7 @@ void srcu_barrier(struct srcu_struct *ssp)  		sdp->srcu_barrier_head.func = srcu_barrier_cb;  		debug_rcu_head_queue(&sdp->srcu_barrier_head);  		if (!rcu_segcblist_entrain(&sdp->srcu_cblist, -					   &sdp->srcu_barrier_head, 0)) { +					   &sdp->srcu_barrier_head)) {  			debug_rcu_head_unqueue(&sdp->srcu_barrier_head);  			atomic_dec(&ssp->srcu_barrier_cpu_cnt);  		}  |