时间管理(四) ---- SMP更新tick职责处理
v3.14.25
系统初始化时会设定哪个CPU更新 jiffies,谁先运行了这段代码谁负责更新
166 static void tick_setup_device(struct tick_device *td,
167 +--- 2 lines: struct clock_event_device *newdev, int cpu,-------- 169 {170 +-- 6 lines: ktime_t next_event;---------------------------------- 176 if (!td->evtdev) {177 +-- 4 lines: If no cpu took the do_timer update, assign it to------ 181 if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) { 182 if (!tick_nohz_full_cpu(cpu)) 183 tick_do_timer_cpu = cpu; 184 else 185 tick_do_timer_cpu = TICK_DO_TIMER_NONE; 186 tick_next_period = ktime_get(); 187 tick_period = ktime_set(0, NSEC_PER_SEC / HZ); 188 } 189 +-- 34 lines: Startup in periodic mode first.------------------------ 223 }
负责更新 jiffies的CPU 在进入idle时会“放弃”更新 jiffies的职责
530 static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, 531 ktime_t now, int cpu) 532 {533 +-- 36 lines: unsigned long seq, last_jiffies, next_jiffies, delta_jiffies;--- 569 /* Schedule the tick, if we are at least one jiffie off */ 570 if ((long)delta_jiffies >= 1) {
571
572 +-- 13 lines: If this cpu is the one which updates jiffies, then-- 585 if (cpu == tick_do_timer_cpu) { 586 tick_do_timer_cpu = TICK_DO_TIMER_NONE; 587 ts-do_timer_last = 1; 588 } else if (tick_do_timer_cpu != TICK_DO_TIMER_NONE) { 589 time_delta = KTIME_MAX; 590 ts->do_timer_last = 0;591 } else if (!ts-do_timer_last) { 592 time_delta = KTIME_MAX;593 } 594 +-- 86 lines: #ifdef CONFIG_NO_HZ_FULL----------------------------- 680 }
其它CPU在处理 timer tick中断时会 检测是否有CPU负责更新jiffies,如果没有则自己负责更新jiffies.
112 static void tick_sched_do_timer(ktime_t now) 113 {114 +-- 10 lines: int cpu = smp_processor_id();----------- 124 if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE) 125 && !tick_nohz_full_cpu(cpu)) 126 tick_do_timer_cpu = cpu;
127 +-- 3 lines: #endif--------------------------------------- 130 if (tick_do_timer_cpu == cpu) 131 tick_do_update_jiffies64(now); 132 }