diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/rcu/tree.c | 4 | ||||
| -rw-r--r-- | kernel/rcu/tree.h | 3 | ||||
| -rw-r--r-- | kernel/rcu/tree_plugin.h | 16 | 
3 files changed, 18 insertions, 5 deletions
| diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index e41dd4131f7a..8e8c6ec1d30f 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -1614,7 +1614,6 @@ static int rcu_future_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)  	int needmore;  	struct rcu_data *rdp = this_cpu_ptr(rsp->rda); -	rcu_nocb_gp_cleanup(rsp, rnp);  	rnp->need_future_gp[c & 0x1] = 0;  	needmore = rnp->need_future_gp[(c + 1) & 0x1];  	trace_rcu_future_gp(rnp, rdp, c, @@ -2010,6 +2009,7 @@ static void rcu_gp_cleanup(struct rcu_state *rsp)  	int nocb = 0;  	struct rcu_data *rdp;  	struct rcu_node *rnp = rcu_get_root(rsp); +	wait_queue_head_t *sq;  	WRITE_ONCE(rsp->gp_activity, jiffies);  	raw_spin_lock_irq_rcu_node(rnp); @@ -2046,7 +2046,9 @@ static void rcu_gp_cleanup(struct rcu_state *rsp)  			needgp = __note_gp_changes(rsp, rnp, rdp) || needgp;  		/* smp_mb() provided by prior unlock-lock pair. */  		nocb += rcu_future_gp_cleanup(rsp, rnp); +		sq = rcu_nocb_gp_get(rnp);  		raw_spin_unlock_irq(&rnp->lock); +		rcu_nocb_gp_cleanup(sq);  		cond_resched_rcu_qs();  		WRITE_ONCE(rsp->gp_activity, jiffies);  		rcu_gp_slow(rsp, gp_cleanup_delay); diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h index 83360b4f4352..10dedfbef09d 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h @@ -621,7 +621,8 @@ static void zero_cpu_stall_ticks(struct rcu_data *rdp);  static void increment_cpu_stall_ticks(void);  static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu);  static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq); -static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp); +static wait_queue_head_t *rcu_nocb_gp_get(struct rcu_node *rnp); +static void rcu_nocb_gp_cleanup(wait_queue_head_t *sq);  static void rcu_init_one_nocb(struct rcu_node *rnp);  static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,  			    bool lazy, unsigned long flags); diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h index 9467a8b7e756..631aff61abe9 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -1811,9 +1811,9 @@ early_param("rcu_nocb_poll", parse_rcu_nocb_poll);   * Wake up any no-CBs CPUs' kthreads that were waiting on the just-ended   * grace period.   */ -static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp) +static void rcu_nocb_gp_cleanup(wait_queue_head_t *sq)  { -	wake_up_all(&rnp->nocb_gp_wq[rnp->completed & 0x1]); +	wake_up_all(sq);  }  /* @@ -1829,6 +1829,11 @@ static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq)  	rnp->need_future_gp[(rnp->completed + 1) & 0x1] += nrq;  } +static wait_queue_head_t *rcu_nocb_gp_get(struct rcu_node *rnp) +{ +	return &rnp->nocb_gp_wq[rnp->completed & 0x1]; +} +  static void rcu_init_one_nocb(struct rcu_node *rnp)  {  	init_waitqueue_head(&rnp->nocb_gp_wq[0]); @@ -2502,7 +2507,7 @@ static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu)  	return false;  } -static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp) +static void rcu_nocb_gp_cleanup(wait_queue_head_t *sq)  {  } @@ -2510,6 +2515,11 @@ static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq)  {  } +static wait_queue_head_t *rcu_nocb_gp_get(struct rcu_node *rnp) +{ +	return NULL; +} +  static void rcu_init_one_nocb(struct rcu_node *rnp)  {  } | 
