diff options
| -rw-r--r-- | kernel/rcutree.c | 5 | ||||
| -rw-r--r-- | kernel/rcutree.h | 1 | ||||
| -rw-r--r-- | kernel/rcutree_plugin.h | 14 | 
3 files changed, 19 insertions, 1 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index c0ed3765ec39..4ec4b14cfba6 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -1403,7 +1403,10 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)  		debug_rcu_head_unqueue(list);  		__rcu_reclaim(rsp->name, list);  		list = next; -		if (++count >= bl) +		/* Stop only if limit reached and CPU has something to do. */ +		if (++count >= bl && +		    (need_resched() || +		     (!is_idle_task(current) && !rcu_is_callbacks_kthread())))  			break;  	} diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 9bcfbc9d16c6..fddff92d6676 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h @@ -455,6 +455,7 @@ static void __init __rcu_init_preempt(void);  static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags);  static void rcu_preempt_boost_start_gp(struct rcu_node *rnp);  static void invoke_rcu_callbacks_kthread(void); +static bool rcu_is_callbacks_kthread(void);  #ifdef CONFIG_RCU_BOOST  static void rcu_preempt_do_callbacks(void);  static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index dbcea6b93aea..adb6e666c6f4 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -1337,6 +1337,15 @@ static void invoke_rcu_callbacks_kthread(void)  }  /* + * Is the current CPU running the RCU-callbacks kthread? + * Caller must have preemption disabled. + */ +static bool rcu_is_callbacks_kthread(void) +{ +	return __get_cpu_var(rcu_cpu_kthread_task) == current; +} + +/*   * Set the affinity of the boost kthread.  The CPU-hotplug locks are   * held, so no one should be messing with the existence of the boost   * kthread. @@ -1780,6 +1789,11 @@ static void invoke_rcu_callbacks_kthread(void)  	WARN_ON_ONCE(1);  } +static bool rcu_is_callbacks_kthread(void) +{ +	return false; +} +  static void rcu_preempt_boost_start_gp(struct rcu_node *rnp)  {  }  | 
