diff options
Diffstat (limited to 'kernel/rcu/srcutree.c')
| -rw-r--r-- | kernel/rcu/srcutree.c | 18 | 
1 files changed, 10 insertions, 8 deletions
diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index 657e6a7d1c03..0c71505f0e19 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -5,7 +5,7 @@   * Copyright (C) IBM Corporation, 2006   * Copyright (C) Fujitsu, 2012   * - * Author: Paul McKenney <[email protected]> + * Authors: Paul McKenney <[email protected]>   *	   Lai Jiangshan <[email protected]>   *   * For detailed explanation of Read-Copy Update mechanism see - @@ -450,7 +450,7 @@ static void srcu_gp_start(struct srcu_struct *ssp)  	spin_unlock_rcu_node(sdp);  /* Interrupts remain disabled. */  	smp_mb(); /* Order prior store to ->srcu_gp_seq_needed vs. GP start. */  	rcu_seq_start(&ssp->srcu_gp_seq); -	state = rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)); +	state = rcu_seq_state(ssp->srcu_gp_seq);  	WARN_ON_ONCE(state != SRCU_STATE_SCAN1);  } @@ -534,7 +534,7 @@ static void srcu_gp_end(struct srcu_struct *ssp)  	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)) -		ssp->srcu_gp_seq_needed_exp = gpseq; +		WRITE_ONCE(ssp->srcu_gp_seq_needed_exp, gpseq);  	spin_unlock_irq_rcu_node(ssp);  	mutex_unlock(&ssp->srcu_gp_mutex);  	/* A new grace period can start at this point.  But only one. */ @@ -550,7 +550,7 @@ static void srcu_gp_end(struct srcu_struct *ssp)  		snp->srcu_have_cbs[idx] = gpseq;  		rcu_seq_set_state(&snp->srcu_have_cbs[idx], 1);  		if (ULONG_CMP_LT(snp->srcu_gp_seq_needed_exp, gpseq)) -			snp->srcu_gp_seq_needed_exp = gpseq; +			WRITE_ONCE(snp->srcu_gp_seq_needed_exp, gpseq);  		mask = snp->srcu_data_have_cbs[idx];  		snp->srcu_data_have_cbs[idx] = 0;  		spin_unlock_irq_rcu_node(snp); @@ -614,7 +614,7 @@ static void srcu_funnel_exp_start(struct srcu_struct *ssp, struct srcu_node *snp  	}  	spin_lock_irqsave_rcu_node(ssp, flags);  	if (ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, s)) -		ssp->srcu_gp_seq_needed_exp = s; +		WRITE_ONCE(ssp->srcu_gp_seq_needed_exp, s);  	spin_unlock_irqrestore_rcu_node(ssp, flags);  } @@ -660,7 +660,7 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,  		if (snp == sdp->mynode)  			snp->srcu_data_have_cbs[idx] |= sdp->grpmask;  		if (!do_norm && ULONG_CMP_LT(snp->srcu_gp_seq_needed_exp, s)) -			snp->srcu_gp_seq_needed_exp = s; +			WRITE_ONCE(snp->srcu_gp_seq_needed_exp, s);  		spin_unlock_irqrestore_rcu_node(snp, flags);  	} @@ -674,7 +674,7 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,  		smp_store_release(&ssp->srcu_gp_seq_needed, s); /*^^^*/  	}  	if (!do_norm && ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, s)) -		ssp->srcu_gp_seq_needed_exp = s; +		WRITE_ONCE(ssp->srcu_gp_seq_needed_exp, s);  	/* If grace period not already done and none in progress, start it. */  	if (!rcu_seq_done(&ssp->srcu_gp_seq, s) && @@ -1079,7 +1079,7 @@ EXPORT_SYMBOL_GPL(srcu_barrier);   */  unsigned long srcu_batches_completed(struct srcu_struct *ssp)  { -	return ssp->srcu_idx; +	return READ_ONCE(ssp->srcu_idx);  }  EXPORT_SYMBOL_GPL(srcu_batches_completed); @@ -1130,7 +1130,9 @@ static void srcu_advance_state(struct srcu_struct *ssp)  			return; /* readers present, retry later. */  		}  		srcu_flip(ssp); +		spin_lock_irq_rcu_node(ssp);  		rcu_seq_set_state(&ssp->srcu_gp_seq, SRCU_STATE_SCAN2); +		spin_unlock_irq_rcu_node(ssp);  	}  	if (rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)) == SRCU_STATE_SCAN2) {  |