微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Linux 时钟管理

Linux 时钟管理

时间:06-13 来源:IBM 点击:

闲状态时仍然会产生周期性的中断,这种频繁的中断迫使 CPU 无法进入更深的睡眠。如果放开这个限制,在系统进入空闲时停止 tick,有工作时恢复 tick,实现完全自由的,根据需要产生 tick 的机制,可以使 CPU 获得更多的睡眠机会以及更深的睡眠,从而进一步节能。dynamic tick 的出现,就是为彻底替换掉周期性的 tick 机制而产生的。周期性运行的 tick 机制需要完成诸如进程时间片的计算,更新 profile,协助 CPU 进行负载均衡等诸多工作,这些工作 dynamic tick 都提供了相应的模拟机制来完成。由于 dynamic tick 的实现需要内核的很多模块的配合,包括了很多实现细节,这里只介绍 dynamic tick 的核心工作机制,以及如何启动和停止 dynamic tick。

Dynamic tick 的核心处理流程

从上文中可知内核时钟子系统支持低精度和高精度两种模式,因此 dynamic tick 也必须有两套对应的处理机制。从清单 5 中可以得知,如果系统支持 hrtimer 的高精度模式,hrtimer 可以在此从低精度模式切换到高精度模式。其实清单 5 还有另外一个重要功能:它也是低精度模式下从周期性 tick 到 dynamic tick 的切换点。如果当前系统不支持高精度模式,系统会尝试切换到 NOHZ 模式,也就是使用 dynamic tick 的模式,当然前提是内核使能了 NOHZ 模式。其核心处理函数如清单 10 所示。这个函数的调用流程如下:

tick_check_oneshot_change tick_nohz_switch_to_nohz tick_switch_to_oneshot(tick_nohz_handler)

清单 10. 低精度模式下 dynamic tick 的核心处理函数
static void tick_nohz_handler(struct clock_event_device *dev) { struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); struct pt_regs *regs = get_irq_regs(); int cpu = smp_processor_id(); ktime_t now = ktime_get(); dev->next_event.tv64 = KTIME_MAX; if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) tick_do_timer_cpu = cpu; /* Check, if the jiffies need an update */ if (tick_do_timer_cpu == cpu) tick_do_update_jiffies64(now); /* * When we are idle and the tick is stopped, we have to touch * the watchdog as we might not schedule for a really long * time. This happens on complete idle SMP systems while * waiting on the login prompt. We also increment the "start * of idle" jiffy stamp so the idle accounting adjustment we * do when we go busy again does not account too much ticks. */ if (ts->tick_stopped) { touch_softlockup_watchdog(); ts->idle_jiffies++; } update_process_times(user_mode(regs)); profile_tick(CPU_PROFILING); while (tick_nohz_reprogram(ts, now)) { now = ktime_get(); tick_do_update_jiffies64(now); } }

在这个函数中,首先模拟周期性 tick device 完成类似的工作:如果当前 CPU 负责全局 tick device 的工作,则更新 jiffies,同时完成对本地 CPU 的进程时间统计等工作。如果当前 tick device 在此之前已经处于停止状态,为了防止 tick 停止时间过长造成 watchdog 超时,从而引发 soft-lockdep 的错误,需要通过调用 touch_softlockup_watchdog 复位软件看门狗防止其溢出。正如代码中注释所描述的,这种情况有可能出现在启动完毕,完全空闲等待登录的 SMP 系统上。最后需要设置下一次 tick 的超时时间。如果 tick_nohz_reprogram 执行时间超过了一个 jiffy,会导致设置的下一次超时时间已经过期,因此需要重新设置,相应的也需要再次更新 jiffies。这里虽然设置了下一次的超时事件,但是由于系统空闲时会停止 tick,因此下一次的超时事件可能发生,也可能不发生。这也正是 dynamic tick 根本特性。

从清单 7 中可以看到,在高精度模式下 tick_sched_timer 用来模拟周期性 tick device 的功能。dynamic tick 的实现也使用了这个函数。这是因为 hrtimer 在高精度模式时必须使用 one-shot 模式的 tick device,这也同时符合 dynamic tick 的要求。虽然使用同样的函数,表面上都会触发周期性的 tick 中断,但是使用 dynamic tick 的系统在空闲时会停止 tick 工作

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top