对内核高精度timer体系的一些分析

因为在vim下输入英文比较方便, 所以一般初稿都是用英文写的.
下面的分析是基于最新的内核(2.6.33)的.

there is not included at current platform commented #
在kernel的time目录里,会根据不同的编译选项来选择不同的tick模式,一般为以下模式(arm)
带#为没有编译进内核的.

obn-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD)        += clockevents.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS)        += tick-common.o
#obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)    += tick-broadcast.o
obj-$(CONFIG_TICK_ONESHOT)            += tick-oneshot.o
obj-$(CONFIG_TICK_ONESHOT)            += tick-sched.o
#obj-$(CONFIG_TIMER_STATS)            += timer_stats.o

 

Currently, the kernel time-keeping is based on nsec.
event_handler is assigned at tick_setup_periodic during initialization, and the value is tick_handle_periodic(before softirq initialization), after softirq initialization, the evt->enent_handler will be assigned to hrtimer_interrupt if hrtimer is enable or no hz handler if hrtimer is disabled and no hz mode is enabled.
hrtimer will be called during hard irq context if it expires, the other hrtimer will be called during softirq context
现在的内核计时的最小单位为纳表,一般的计时都是表和纳秒的组合.
如果hrtimer和no hz模式被始能,时钟中断的处理方式会有些不同.一开始(在软中断初始化之前)event_handler是指向tick_handle_periodic,在软中断初始化之后,evt->enent_handler将根据hrtimer与no hz是否始能,指向对应的函数.如果两个都始能,就指向hrtimer_interrupt, 如果hrtimer不始能,就指向tick_nohz_handler.
在内核的timer系统中会经常看到mult,shift,min_delta_ns等名词.下面具体说一下它们的意思,
先列一个内核的结构以及相应的注释.
/**
 * struct clock_event_device - clock event device descriptor
 * @name:        ptr to clock event name
 * @features:        features
 * @max_delta_ns:    maximum delta value in ns
 * @min_delta_ns:    minimum delta value in ns
 * @mult:        nanosecond to cycles multiplier
 * @shift:        nanoseconds to cycles divisor (power of two)
 * @rating:        variable to rate clock event devices
 * @irq:        IRQ number (only for non CPU local devices)
 * @cpumask:        cpumask to indicate for which CPUs this device works
 * @set_next_event:    set next event function
 * @set_mode:        set mode function
 * @event_handler:    Assigned by the framework to be called by the low
 *            level handler of the event source
 * @broadcast:        function to broadcast events
 * @list:        list head for the management code
 * @mode:        operating mode assigned by the management code
 * @next_event:        local storage for the next event in oneshot mode
 */
struct clock_event_device {
    const char        *name;
    unsigned int        features;
    u64            max_delta_ns;
    u64            min_delta_ns;
    u32            mult;
    u32            shift;
    int            rating;
    int            irq;
    const struct cpumask    *cpumask;
    int            (*set_next_event)(unsigned long evt,
                          struct clock_event_device *);
    void            (*set_mode)(enum clock_event_mode mode,
                        struct clock_event_device *);
    void            (*event_handler)(struct clock_event_device *);
    void            (*broadcast)(const struct cpumask *mask);
    struct list_head    list;
    enum clock_event_mode    mode;
    ktime_t            next_event;
};
freq = mult/(2^shift): freq is how many ticks for ns, for our platform, it is 1/1000.
mult和shift是用来转化timer的tick和纳秒的.freq = mult/(2^shift)中,freq表示一个ns有多少个tick,如果tick是1M,那freq就是1/1000.

The hrtimer will be called at both hardirq condition (at evt->event_handler) and softirq context.The condition which adjust the timer is expired or not is calling ktime_get() to get current kernel time; it will reture tick count at timer register finally. But the software timer is different, it uses jiffies to adjust whether the timer is expired or not
hrtimer的回调函数会同时在硬件中断上下文和软中断上下文中调用,判断timer时候过期是用ktime_get()函数,该函数最终会去读timer的tick来更新内核的时间.而软件timer就不同了,它是根据jiffies来判断timer是否过期的.

 

NOTICE: The hrtimer expires value should be larger than 2 ticks (currently is 2000ns), otherwise, the hrtimer which is setting at hrtimer's callback function will be called a little late, about more than 40-50 ticks
有一个要注意,hrtimer的过期值不能设的太小,如果少于3个tick,并且下一次hrtimer的设定就是在上一次hrtimer的回调函数里,且过期时间也是少于3个tick的,这样在执行过3次hrtimer以后就会触发hrtimer_interrupt里的一个错误条件(将已经过期的timer误认为没有过期,且3次出现这样的情况),这个错误条件一旦成立,它的会调函数可能要过40-50个tick(具体跟回调函数的执行时间有关)才可能会执行.

 

在nohz和highres模式下, timer中断的interval为以highres timer和software timer expires中较小的一个.

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值