大體流程:
run_timer_softirq
hrtimer_run_pending
hrtimer_switch_to_hres
tick_setup_sched_timer
hrtimer_init/*settup hr tick timer,tick-sched.c*/
tick_sched_timer /*hard irq context*/
plat_irq_dispatch
nlm_common_timer_interrupt
do_IRQ
desc->handle_irq
c0_compare_interrupt
struct clock_event_device *cd;
cd = &per_cpu(mips_clockevent_device, cpu);
cd->event_handler(cd);
cd->event_handler
hrtimer_interrupt
tick_sched_timer
update_process_times
run_local_timers
hrtimer_run_queues (當前tick timer已被摘除,不在queue中,因此將自己再次加入紅黑樹並觸發下一次時鐘)
32內核的高精度定時運行環境是在硬中斷下
1)系統剛初始化時,clock_device dev的 event_handler是一個空函數,後面被替換成tick_handle_periodic,
tick_check_new_device--->
tick_setup_device--->
tick_setup_periodic-->
tick_set_periodic_handler--->
dev->event_handler = tick_handle_periodic;
接着主動觸發一個時鐘中斷
clockevents_program_event---> dev->set_next_event 操作compare寄存器來觸發
2)timer_interrupt-->event_handler-->tick_handle_periodic---> tick_periodic--->
update_process_times--->run_local_timers--->raise_softirq(TIMER_SOFTIRQ);
詳細的流程(plat_irq_dispatch
nlm_common_timer_interrupt
do_IRQ
desc->handle_irq
c0_compare_interrupt
struct clock_event_device *cd;
cd = &per_cpu(mips_clockevent_device, cpu);
cd->event_handler(cd);
cd->event_handler
)
3)軟中斷裏,每次都在hrtimer_run_pending嘗試進行高精度時鐘切換,如果切換不成功,即沒有
配置高精度定時器,則在run_timer_softirq裏走timer wheel定時器。
static void run_timer_softirq(struct softirq_action *h)
{
struct tvec_base *base = __get_cpu_var(tvec_bases);
perf_event_do_pending();
hrtimer_run_pending();
if (time_after_eq(jiffies, base->timer_jiffies))
__run_timers(base);
}
run_timer_softirq-->hrtimer_run_pending--->hrtimer_switch_to_hres-->event_handler = hrtimer_interrupt;
event_handler被換成hrtimer_interrupt
This _is_ ugly: We have to check in the softirq context,
whether we can switch to highres and / or nohz mode.
if (tick_check_oneshot_change(!hrtimer_is_hres_enabled()))
hrtimer_switch_to_hres();
hrtimer_switch_to_hres-->tick_init_highres-->tick_switch_to_oneshot(hrtimer_interrupt);-->dev->event_handler = handler;
4)然後就是高精度定時器處理流程了
timer_interrupt-->event_handler--->hrtimer_interrupt-->
在高精度時鐘切換完畢後,會有一個嘗試啓動週期定時器即系統心跳的操作。
tick_setup_sched_timer
如果系統沒有高精度時鐘支持(即沒有count compare), 則在低精度模式下如何運作?
運行流程是什麼?