LCOV - code coverage report
Current view: top level - kernel/cpu - idle.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 21 45 46.7 %
Date: 2014-02-18 Functions: 0 10 0.0 %
Branches: 12 26 46.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Generic entry point for the idle threads
       3                 :            :  */
       4                 :            : #include <linux/sched.h>
       5                 :            : #include <linux/cpu.h>
       6                 :            : #include <linux/tick.h>
       7                 :            : #include <linux/mm.h>
       8                 :            : #include <linux/stackprotector.h>
       9                 :            : 
      10                 :            : #include <asm/tlb.h>
      11                 :            : 
      12                 :            : #include <trace/events/power.h>
      13                 :            : 
      14                 :            : static int __read_mostly cpu_idle_force_poll;
      15                 :            : 
      16                 :          0 : void cpu_idle_poll_ctrl(bool enable)
      17                 :            : {
      18         [ #  # ]:          0 :         if (enable) {
      19                 :          0 :                 cpu_idle_force_poll++;
      20                 :            :         } else {
      21                 :          0 :                 cpu_idle_force_poll--;
      22 [ #  # ][ #  # ]:          0 :                 WARN_ON_ONCE(cpu_idle_force_poll < 0);
                 [ #  # ]
      23                 :            :         }
      24                 :          0 : }
      25                 :            : 
      26                 :            : #ifdef CONFIG_GENERIC_IDLE_POLL_SETUP
      27                 :          0 : static int __init cpu_idle_poll_setup(char *__unused)
      28                 :            : {
      29                 :          0 :         cpu_idle_force_poll = 1;
      30                 :          0 :         return 1;
      31                 :            : }
      32                 :            : __setup("nohlt", cpu_idle_poll_setup);
      33                 :            : 
      34                 :          0 : static int __init cpu_idle_nopoll_setup(char *__unused)
      35                 :            : {
      36                 :          0 :         cpu_idle_force_poll = 0;
      37                 :          0 :         return 1;
      38                 :            : }
      39                 :            : __setup("hlt", cpu_idle_nopoll_setup);
      40                 :            : #endif
      41                 :            : 
      42                 :            : static inline int cpu_idle_poll(void)
      43                 :            : {
      44                 :        339 :         rcu_idle_enter();
      45                 :        339 :         trace_cpu_idle_rcuidle(0, smp_processor_id());
      46                 :            :         local_irq_enable();
      47         [ +  + ]: 2216594153 :         while (!tif_need_resched())
      48                 : 2216593814 :                 cpu_relax();
      49                 :        339 :         trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
      50                 :        339 :         rcu_idle_exit();
      51                 :            :         return 1;
      52                 :            : }
      53                 :            : 
      54                 :            : /* Weak implementations for optional arch specific functions */
      55                 :          0 : void __weak arch_cpu_idle_prepare(void) { }
      56                 :          0 : void __weak arch_cpu_idle_enter(void) { }
      57                 :          0 : void __weak arch_cpu_idle_exit(void) { }
      58                 :          0 : void __weak arch_cpu_idle_dead(void) { }
      59                 :          0 : void __weak arch_cpu_idle(void)
      60                 :            : {
      61                 :          0 :         cpu_idle_force_poll = 1;
      62                 :            :         local_irq_enable();
      63                 :          0 : }
      64                 :            : 
      65                 :            : /*
      66                 :            :  * Generic idle loop implementation
      67                 :            :  */
      68                 :          0 : static void cpu_idle_loop(void)
      69                 :            : {
      70                 :            :         while (1) {
      71                 :    5356797 :                 tick_nohz_idle_enter();
      72                 :            : 
      73         [ +  + ]:   11038962 :                 while (!need_resched()) {
      74                 :            :                         check_pgt_cache();
      75                 :    5682033 :                         rmb();
      76                 :            : 
      77         [ -  + ]:    5682266 :                         if (cpu_is_offline(smp_processor_id()))
      78                 :          0 :                                 arch_cpu_idle_dead();
      79                 :            : 
      80                 :            :                         local_irq_disable();
      81                 :    5682295 :                         arch_cpu_idle_enter();
      82                 :            : 
      83                 :            :                         /*
      84                 :            :                          * In poll mode we reenable interrupts and spin.
      85                 :            :                          *
      86                 :            :                          * Also if we detected in the wakeup from idle
      87                 :            :                          * path that the tick broadcast device expired
      88                 :            :                          * for us, we don't want to go deep idle as we
      89                 :            :                          * know that the IPI is going to arrive right
      90                 :            :                          * away
      91                 :            :                          */
      92 [ +  + ][ +  + ]:    5682277 :                         if (cpu_idle_force_poll || tick_check_broadcast_expired()) {
      93                 :            :                                 cpu_idle_poll();
      94                 :            :                         } else {
      95         [ +  + ]:    5681900 :                                 if (!current_clr_polling_and_test()) {
      96                 :            :                                         stop_critical_timings();
      97                 :    5637493 :                                         rcu_idle_enter();
      98                 :    5637495 :                                         arch_cpu_idle();
      99 [ -  + ][ #  # ]:    5637548 :                                         WARN_ON_ONCE(irqs_disabled());
                 [ #  # ]
     100                 :    5637548 :                                         rcu_idle_exit();
     101                 :            :                                         start_critical_timings();
     102                 :            :                                 } else {
     103                 :            :                                         local_irq_enable();
     104                 :            :                                 }
     105                 :            :                                 __current_set_polling();
     106                 :            :                         }
     107                 :    5682301 :                         arch_cpu_idle_exit();
     108                 :            :                         /*
     109                 :            :                          * We need to test and propagate the TIF_NEED_RESCHED
     110                 :            :                          * bit here because we might not have send the
     111                 :            :                          * reschedule IPI to idle tasks.
     112                 :            :                          */
     113                 :            :                         if (tif_need_resched())
     114                 :            :                                 set_preempt_need_resched();
     115                 :            :                 }
     116                 :    5356929 :                 tick_nohz_idle_exit();
     117                 :    5356926 :                 schedule_preempt_disabled();
     118                 :    5356797 :         }
     119                 :            : }
     120                 :            : 
     121                 :          0 : void cpu_startup_entry(enum cpuhp_state state)
     122                 :            : {
     123                 :            :         /*
     124                 :            :          * This #ifdef needs to die, but it's too late in the cycle to
     125                 :            :          * make this generic (arm and sh have never invoked the canary
     126                 :            :          * init for the non boot cpus!). Will be fixed in 3.11
     127                 :            :          */
     128                 :            : #ifdef CONFIG_X86
     129                 :            :         /*
     130                 :            :          * If we're the non-boot CPU, nothing set the stack canary up
     131                 :            :          * for us. The boot CPU already has it initialized but no harm
     132                 :            :          * in doing it again. This is a good place for updating it, as
     133                 :            :          * we wont ever return from this function (so the invalid
     134                 :            :          * canaries already on the stack wont ever trigger).
     135                 :            :          */
     136                 :            :         boot_init_stack_canary();
     137                 :            : #endif
     138                 :            :         __current_set_polling();
     139                 :          0 :         arch_cpu_idle_prepare();
     140                 :          0 :         cpu_idle_loop();
     141                 :            : }

Generated by: LCOV version 1.9