diff options
| -rw-r--r-- | kernel/rcutiny.c | 31 | 
1 files changed, 16 insertions, 15 deletions
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c index 547b1fe5b05..e4163c5af1d 100644 --- a/kernel/rcutiny.c +++ b/kernel/rcutiny.c @@ -56,24 +56,27 @@ static void __call_rcu(struct rcu_head *head,  static long long rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;  /* Common code for rcu_idle_enter() and rcu_irq_exit(), see kernel/rcutree.c. */ -static void rcu_idle_enter_common(long long oldval) +static void rcu_idle_enter_common(long long newval)  { -	if (rcu_dynticks_nesting) { +	if (newval) {  		RCU_TRACE(trace_rcu_dyntick("--=", -					    oldval, rcu_dynticks_nesting)); +					    rcu_dynticks_nesting, newval)); +		rcu_dynticks_nesting = newval;  		return;  	} -	RCU_TRACE(trace_rcu_dyntick("Start", oldval, rcu_dynticks_nesting)); +	RCU_TRACE(trace_rcu_dyntick("Start", rcu_dynticks_nesting, newval));  	if (!is_idle_task(current)) {  		struct task_struct *idle = idle_task(smp_processor_id());  		RCU_TRACE(trace_rcu_dyntick("Error on entry: not idle task", -					    oldval, rcu_dynticks_nesting)); +					    rcu_dynticks_nesting, newval));  		ftrace_dump(DUMP_ALL);  		WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",  			  current->pid, current->comm,  			  idle->pid, idle->comm); /* must be idle task! */  	} +	barrier(); +	rcu_dynticks_nesting = newval;  	rcu_sched_qs(0); /* implies rcu_bh_qsctr_inc(0) */  } @@ -84,17 +87,16 @@ static void rcu_idle_enter_common(long long oldval)  void rcu_idle_enter(void)  {  	unsigned long flags; -	long long oldval; +	long long newval;  	local_irq_save(flags); -	oldval = rcu_dynticks_nesting;  	WARN_ON_ONCE((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) == 0);  	if ((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) ==  	    DYNTICK_TASK_NEST_VALUE) -		rcu_dynticks_nesting = 0; +		newval = 0;  	else -		rcu_dynticks_nesting  -= DYNTICK_TASK_NEST_VALUE; -	rcu_idle_enter_common(oldval); +		newval = rcu_dynticks_nesting - DYNTICK_TASK_NEST_VALUE; +	rcu_idle_enter_common(newval);  	local_irq_restore(flags);  }  EXPORT_SYMBOL_GPL(rcu_idle_enter); @@ -105,13 +107,12 @@ EXPORT_SYMBOL_GPL(rcu_idle_enter);  void rcu_irq_exit(void)  {  	unsigned long flags; -	long long oldval; +	long long newval;  	local_irq_save(flags); -	oldval = rcu_dynticks_nesting; -	rcu_dynticks_nesting--; -	WARN_ON_ONCE(rcu_dynticks_nesting < 0); -	rcu_idle_enter_common(oldval); +	newval = rcu_dynticks_nesting - 1; +	WARN_ON_ONCE(newval < 0); +	rcu_idle_enter_common(newval);  	local_irq_restore(flags);  }  |