diff options
Diffstat (limited to 'kernel/sched/idle.c')
| -rw-r--r-- | kernel/sched/idle.c | 47 | 
1 files changed, 13 insertions, 34 deletions
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index f26ab2675f7d..e9ef66be2870 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -51,18 +51,22 @@ __setup("hlt", cpu_idle_nopoll_setup);  static noinline int __cpuidle cpu_idle_poll(void)  { +	instrumentation_begin();  	trace_cpu_idle(0, smp_processor_id());  	stop_critical_timings(); -	ct_idle_enter(); -	local_irq_enable(); +	ct_cpuidle_enter(); +	raw_local_irq_enable();  	while (!tif_need_resched() &&  	       (cpu_idle_force_poll || tick_check_broadcast_expired()))  		cpu_relax(); +	raw_local_irq_disable(); -	ct_idle_exit(); +	ct_cpuidle_exit();  	start_critical_timings();  	trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id()); +	local_irq_enable(); +	instrumentation_end();  	return 1;  } @@ -75,7 +79,6 @@ void __weak arch_cpu_idle_dead(void) { }  void __weak arch_cpu_idle(void)  {  	cpu_idle_force_poll = 1; -	raw_local_irq_enable();  }  /** @@ -85,44 +88,20 @@ void __weak arch_cpu_idle(void)   */  void __cpuidle default_idle_call(void)  { -	if (current_clr_polling_and_test()) { -		local_irq_enable(); -	} else { - +	instrumentation_begin(); +	if (!current_clr_polling_and_test()) {  		trace_cpu_idle(1, smp_processor_id());  		stop_critical_timings(); -		/* -		 * arch_cpu_idle() is supposed to enable IRQs, however -		 * we can't do that because of RCU and tracing. -		 * -		 * Trace IRQs enable here, then switch off RCU, and have -		 * arch_cpu_idle() use raw_local_irq_enable(). Note that -		 * ct_idle_enter() relies on lockdep IRQ state, so switch that -		 * last -- this is very similar to the entry code. -		 */ -		trace_hardirqs_on_prepare(); -		lockdep_hardirqs_on_prepare(); -		ct_idle_enter(); -		lockdep_hardirqs_on(_THIS_IP_); - +		ct_cpuidle_enter();  		arch_cpu_idle(); - -		/* -		 * OK, so IRQs are enabled here, but RCU needs them disabled to -		 * turn itself back on.. funny thing is that disabling IRQs -		 * will cause tracing, which needs RCU. Jump through hoops to -		 * make it 'work'. -		 */ -		raw_local_irq_disable(); -		lockdep_hardirqs_off(_THIS_IP_); -		ct_idle_exit(); -		lockdep_hardirqs_on(_THIS_IP_); -		raw_local_irq_enable(); +		ct_cpuidle_exit();  		start_critical_timings();  		trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());  	} +	local_irq_enable(); +	instrumentation_end();  }  static int call_cpuidle_s2idle(struct cpuidle_driver *drv,  |