방갑습니다~ 이우영입니다.


오늘은 저번시간에 이어서 swapper를 분석해 보겠습니다.


arch/arm/kernel/process.c에 보면 cpu_idle 함수가 있습니다.


 147void cpu_idle(void)
 148{
 149        local_fiq_enable();
 150
 151        /* endless idle loop with no priority at all */
 152        while (1) {
 153                void (*idle)(void) = pm_idle;
 154
 155#ifdef CONFIG_HOTPLUG_CPU
 156                if (cpu_is_offline(smp_processor_id())) {
 157                        leds_event(led_idle_start);
 158                        cpu_die();
 159                }
 160#endif
 161
 162                if (!idle)
 163                        idle = default_idle;
 164                leds_event(led_idle_start);
 165                tick_nohz_stop_sched_tick(1);
 166                while (!need_resched())
 167                        idle();
 168                leds_event(led_idle_end);
 169                tick_nohz_restart_sched_tick();
 170                preempt_enable_no_resched();
 171                schedule();
 172                preempt_disable();
 173        }
 174}

cpu_idle이 시작하면 149 라인에서 fiq가 동작 할 수 있도록 arm의 cpsr의 값을 설정 해 줍니다.
(idle 상태에 빠져들면 fiq를 이용해 휴면상태에서 빠져나옵니다.)

그리고 무한 루프를 돌기 시작합니다. 
(리눅스가 끝날때까지 멈추지 않습니다 ㅎㅎㅎ)

153 라인에서 매번 pm_idle 함수를 등록 해줍니다. 보통 pm_idle 함수에 전력을 낮춰 주는 부분이 들어있습니다.

162 라인을 보면 idle 에 등록된 함수의 주소가 없을 경우 default_idle 함수를 등록 합니다.

 130static void default_idle(void)
 131{
 132        if (hlt_counter)
 133                cpu_relax();
 134        else {
 135                local_irq_disable();
 136                if (!need_resched())
 137                        arch_idle();
 138                local_irq_enable();
 139        }
 140}

hit_counter가 0일 경우 wakeup call의 미스를 방지하기위해 irq를 금지하고 arch_idle을 실행합니다.

arch_idle같은 경우는 아키택처에 따라 달라지지만 s3c6410은 아무일도 처리 하지 않습니다.

다시 cpu_idle을 보면 164 라인에서 휴면상태에 들어가는걸 알리기위해 led를 제어해줍니다.

165 라인에서 idle tick을 중지 시키고 tickless모드로 들어갑니다.

166 라인부터 idle에 들어가게됩니다. 

need_resched 함수에서 flag값을 확인해서 스케줄이 필요한지 확인하고 없으면 idle에 등록된 함수를 

실행 합니다.

루프를 빠져나오면 타이머를 다시 실행시키고 led도 제어하고 스케줄러를 호출해서 idle 상태가 끝납니다.
(다시 idle 에 들어오면 위 상황을 반복 하겠죠?)


정리



정신이 없내요 ㅎㅎ 간단하게 정리를 해보겠습니다.

idle 모드에 들어오면 idle 에 pm_idle or default_idle 함수를 등록합니다.

led를 이용하여 idle 상태인것을 알리고 tickless 모드로 들어간다.

스케줄이 필요할 때 까지 idle 함수를 수행합니다.

스케줄이 필요해지만 루프를 빠져나와 타이머를 동작시키고, led를 제어해 idle이 끝났음을 알리고

스케줄러를 호출하여 다른 프로세스를 실행 합니다.



여기까지 cpu_idle 의 동작 흐름을 알아 봤습니다.

cpu_idle의 가장 핵심은 pm_idle 에서 어떻게 파워를 세이브 하는가 입니다.

이부분은 다음시간에 이어서 하도록 하겠습니다.