Linux hrtimer_interrupt高精度定时器到期回调执行hrtimerhigh-resolution timer是Linux内核提供的高精度定时器机制基于时钟事件设备clock_event_device而非传统的jiffies轮询。hrtimer_interrupt是hrtimer子系统的核心中断处理函数在硬件时钟中断触发时被调用负责遍历红黑树中所有已经到期的定时器并执行其回调。hrtimer的底层数据组织依赖于红黑树。每个CPU维护一个struct hrtimer_cpu_base包含active_bases位图和各clock_base的根节点struct hrtimer_cpu_base {raw_spinlock_t lock;unsigned int cpu;unsigned int active_bases;unsigned int clock_was_set_seq;unsigned int hres_active;unsigned int in_hrtirq;unsigned int nr_events;unsigned int nr_retries;unsigned int nr_hangs;ktime_t expires_next;struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES];};每个hrtimer_clock_base包含红黑树根节点、first指针指向最早到期的定时器、分辨率和偏移量等字段。定时器按照expires绝对到期时间插入红黑树最早到期的定时器位于树的最左节点。hrtimer_interrupt的入口定义如下void hrtimer_interrupt(struct clock_event_device *dev){struct hrtimer_cpu_base *cpu_base this_cpu_ptr(hrtimer_bases);ktime_t expires_next, now, entry_time;int retries 0;cpu_base-nr_events;dev-next_event KTIME_MAX;raw_spin_lock(cpu_base-lock);entry_time now hrtimer_update_base(cpu_base);retry:cpu_base-in_hrtirq 1;cpu_base-expires_next KTIME_MAX;__hrtimer_run_queues(cpu_base, now);expires_next __hrtimer_get_next_event(cpu_base);cpu_base-in_hrtirq 0;raw_spin_unlock(cpu_base-lock);if (expires_next KTIME_MAX ||!tick_program_event(expires_next, 0)) {return;}raw_spin_lock(cpu_base-lock);now hrtimer_update_base(cpu_base);if (now - expires_next 0) {cpu_base-expires_next expires_next;raw_spin_unlock(cpu_base-lock);tick_program_event(expires_next, 1);return;}if (retries 3)goto retry;cpu_base-nr_hangs;cpu_base-expires_next now;raw_spin_unlock(cpu_base-lock);tick_program_event(now, 1);}hrtimer_interrupt首先调用hrtimer_update_base更新基准时间包括CLOCK_MONOTONIC和CLOCK_REALTIME的偏移修正。然后调用__hrtimer_run_queues遍历所有到期的定时器static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now){struct hrtimer_clock_base *base;unsigned int active cpu_base-active_bases;for_each_active_base(base, cpu_base, active) {struct hrtimer *timer;ktime_t basenow;basenow ktime_add(now, base-offset);while ((timer timerqueue_getnext(base-active))) {if (basenow timer-node.expires)break;__remove_hrtimer(cpu_base, base, timer, HRTIMER_STATE_CALLBACK, 0);raw_spin_unlock(cpu_base-lock);__run_hrtimer(timer, basenow);raw_spin_lock(cpu_base-lock);if (cpu_base-in_hrtirq retries HRTIMER_MAX_RETRIES)break;}}}遍历从红黑树的first节点开始逐一检查定时器是否到期。若到期则从红黑树移除并执行回调。此处关键优化是每次执行回调前释放cpu_base-lock避免回调函数中可能的阻塞操作导致其他CPU无法访问hrtimer。__run_hrtimer完成定时器回调执行的准备工作static void __run_hrtimer(struct hrtimer *timer, ktime_t *now){struct hrtimer_clock_base *base timer-base;enum hrtimer_restart (*fn)(struct hrtimer *);enum hrtimer_restart restart;timer-state ~HRTIMER_STATE_ENQUEUED;timer-state | HRTIMER_STATE_CALLBACK;fn timer-function;restart fn(timer);timer-state ~HRTIMER_STATE_CALLBACK;if (restart ! HRTIMER_NORESTART) {BUG_ON(timer-state HRTIMER_STATE_ENQUEUED);enqueue_hrtimer(timer, base, HRTIMER_MODE_ABS);}}回调函数返回enum hrtimer_restart类型HRTIMER_NORESTART表示一次性定时器不需要重新插入HRTIMER_RESTART表示需要重新启动enqueue_hrtimer将其重新插入红黑树。__hrtimer_get_next_event计算当前CPU上最近的到期时间用于编程clock_event_device的下一次中断static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base){struct hrtimer_clock_base *base;unsigned int active cpu_base-active_bases;ktime_t expires_next KTIME_MAX;for_each_active_base(base, cpu_base, active) {struct hrtimer *timer;timer timerqueue_getnext(base-active);if (timer)expires_next ktime_min(expires_next,ktime_sub(timer-node.expires,base-offset));}return expires_next;}若tick_program_event编程中断失败例如硬件无法支持如此短的时间间隔hrtimer_interrupt进入重试逻辑。连续3次重试后设置nr_hangs计数器并将中断强制编程到当前时间点避免活锁。hrtimer_interrupt的精度取决于底层clock_event_device的精度。在支持高精度事件设备的硬件上可以达到纳秒级精度在使用普通tick设备的模拟模式下hrtimer_interrupt退化为tick级别的精度检查。内核通过hrtimer_hres_active区分两种模式在切换时通过hrtimer_switch_to_hres进行热切换。