diff options
Diffstat (limited to 'kernel/rcutree_plugin.h')
| -rw-r--r-- | kernel/rcutree_plugin.h | 33 | 
1 files changed, 23 insertions, 10 deletions
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index d084ae3f281..170814dc418 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -28,6 +28,7 @@  #include <linux/gfp.h>  #include <linux/oom.h>  #include <linux/smpboot.h> +#include <linux/tick.h>  #define RCU_KTHREAD_PRIO 1 @@ -1705,7 +1706,7 @@ static void rcu_prepare_for_idle(int cpu)  		return;  	/* If this is a no-CBs CPU, no callbacks, just return. */ -	if (is_nocb_cpu(cpu)) +	if (rcu_is_nocb_cpu(cpu))  		return;  	/* @@ -1747,7 +1748,7 @@ static void rcu_cleanup_after_idle(int cpu)  	struct rcu_data *rdp;  	struct rcu_state *rsp; -	if (is_nocb_cpu(cpu)) +	if (rcu_is_nocb_cpu(cpu))  		return;  	rcu_try_advance_all_cbs();  	for_each_rcu_flavor(rsp) { @@ -2052,7 +2053,7 @@ static void rcu_init_one_nocb(struct rcu_node *rnp)  }  /* Is the specified CPU a no-CPUs CPU? */ -static bool is_nocb_cpu(int cpu) +bool rcu_is_nocb_cpu(int cpu)  {  	if (have_rcu_nocb_mask)  		return cpumask_test_cpu(cpu, rcu_nocb_mask); @@ -2110,7 +2111,7 @@ static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,  			    bool lazy)  { -	if (!is_nocb_cpu(rdp->cpu)) +	if (!rcu_is_nocb_cpu(rdp->cpu))  		return 0;  	__call_rcu_nocb_enqueue(rdp, rhp, &rhp->next, 1, lazy);  	if (__is_kfree_rcu_offset((unsigned long)rhp->func)) @@ -2134,7 +2135,7 @@ static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp,  	long qll = rsp->qlen_lazy;  	/* If this is not a no-CBs CPU, tell the caller to do it the old way. */ -	if (!is_nocb_cpu(smp_processor_id())) +	if (!rcu_is_nocb_cpu(smp_processor_id()))  		return 0;  	rsp->qlen = 0;  	rsp->qlen_lazy = 0; @@ -2306,11 +2307,6 @@ static void rcu_init_one_nocb(struct rcu_node *rnp)  {  } -static bool is_nocb_cpu(int cpu) -{ -	return false; -} -  static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,  			    bool lazy)  { @@ -2337,3 +2333,20 @@ static bool init_nocb_callback_list(struct rcu_data *rdp)  }  #endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */ + +/* + * An adaptive-ticks CPU can potentially execute in kernel mode for an + * arbitrarily long period of time with the scheduling-clock tick turned + * off.  RCU will be paying attention to this CPU because it is in the + * kernel, but the CPU cannot be guaranteed to be executing the RCU state + * machine because the scheduling-clock tick has been disabled.  Therefore, + * if an adaptive-ticks CPU is failing to respond to the current grace + * period and has not be idle from an RCU perspective, kick it. + */ +static void rcu_kick_nohz_cpu(int cpu) +{ +#ifdef CONFIG_NO_HZ_FULL +	if (tick_nohz_full_cpu(cpu)) +		smp_send_reschedule(cpu); +#endif /* #ifdef CONFIG_NO_HZ_FULL */ +}  |