免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4814 | 回复: 4
打印 上一主题 下一主题

zx_wing,motalelf,bluesky_jxc,我们来研究一下 timer interrupt吧! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-04-09 15:48 |只看该作者 |倒序浏览
关键是0号中断。  

麻烦之处是: HPET和PIT的代码都要分析, 而且还要涉及到 教新的 hrtimer和 dynamic tick,以及相关的clock event 模型。 等。


这里有一份带着很多问题的笔记:
==============================
    PIT的ISR是timer_interrupt, LAPIC Timer的ISR是smp_apic_timer_interrupt。
   
    塑料袋这么说的: SMP上的调度,每个CPU(不管是BSP还是AP)都只用LAPIC Timer来做。
                      
                   问: 为什么用LAPIC Timer?
                   答: kernel想把各个CPU的调度时间错开

                   问: 那么PIT中断用来做什么?
                   答: 只是更新jiffies。

                   问: PIT的ISR谁来执行? 一定是BSP吗?
                   答: 不一定,服从IO-APIC和LAPICs的仲裁。

                   问: 那怎么仲裁? IO-APIC的IRQ redirection table中,PIT占的那个entry,其destination
                       怎么设置?
                   答(by alb): 不知道IO-APIC怎么设置那个IRTE。但是0号中断只能有CPU0来处理,这是在irq0这
                       个irqaction的mask成员中规定好了的。(见下)

    谨案:(from 2.6.25-rc7/rc8)
    ==========================

    hrtimer引入到内核中(2.6.17?)时,增强了clock event模型。 在当前内核里,有3种中断源将自己注册为一个
    clock_event_device:

           
        1) LAPIC Timer (每个CPU一个lapic_events)
           arch/x86/kernel/apic_32.c,         setup_APIC_timer():
               
                clockevents_register_device(levt);
          
           嗯,lapic_clockevent是每个lapic_events的默认值,每个CPU都在setup_APIC_Timer中用它对lapic_events
           进行初始化。

        2) HPET
           arch/x86/kernel/hpet.c,         hpet_legacy_clockevent_register():

                   clockevents_register_device(&hpet_clockevent);

        3) PIT
           arch/x86/kernel/i8253.c,         setup_pit_timer():
                  
                clockevents_register_device(&pit_clockevent);


    同时,系统中有一个唯一的global_clock_event指针,从代码上来看,它或者被赋值为&pit_clockevent,或者
    被赋值为hpet_clockevent。 我的理解是,只要CONFIG_HPET_TIMER=y,那么就是后者。 而且,LAPIC Timer只
    能是一种Local Interrupt Source,因此不可能用来给global_clock_event赋值。

    //FIXME
    现在的关键问题是: 如何确定这3种clockevent的event_handler成员分别是在哪里赋值的? 各自赋值为谁?
    注意这3个静态数据结构:hpet_clockevent、pit_clockevent和lapic_clockevent都没有初始化其event_handler
    成员。

    这个问题在后边回答。


    内核中检查0号中断的中断源为HPET还是PIT的代码流程是:
   
    start_kernel() > time_init() > choose_time_init() == hpet_time_init:

                void __init hpet_time_init(void)
                {
                        if (!hpet_enable())
                                setup_pit_timer();
                        time_init_hook();
                }

     注意,如果HPET失败,则使用PIT。 做完这个选择之后进行0号中断的相关设置。

     -> HPET的情况:
             hpet_enable() > hpet_legacy_clockevent_register() :
                    
                clockevents_register_device(&hpet_clockevent);
                global_clock_event = &hpet_clockevent;

     -> PIT的情况:
             setup_pit_timer() :
               
                clockevents_register_device(&pit_clockevent);
                global_clock_event = &pit_clockevent;

     -> 设置完中断源后:
             time_init_hook():

                /**
                 * static struct irqaction irq0  = {
                 *         .handler = timer_interrupt,
                 *         .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL,
                 *         .mask = CPU_MASK_NONE,
                 *         .name = "timer"
                 * };
                 */
               
                irq0.mask = cpumask_of_cpu(0);
                setup_irq(0, &irq0);
       
        可见, 不管是其中断源是HPET还是PIT, 0号中断只能由CPU0来处理,其处理例程为timer_interrupt。

       
    event_handler的赋值:
    ===================
    注意这3个静态数据结构:hpet_clockevent、pit_clockevent和lapic_clockevent都没有初始化其
    event_handler。

    注意注册一个clockevents设备时:

            clockevents_register_device() > clockevents_do_notify(CLOCK_EVT_NOTIFY_ADD, dev) >
            raw_notifier_call_chain(&clockevents_chain, reason, dev) >
            __raw_notifier_call_chain(nh, val, v, -1, NULL) >
            notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls) :
                   
                ...
                ret = nb->notifier_call(nb, val, v); /* 注意这个参数v,就是clockevents_register_device
                                                      * 的参数clock_event_device *dev
                                                      *
                                                      * 而参数nb,就是&clockevents_chain
                                                      */
   
    这样就在clockevents_chain这个struct raw_notifier_head中注册了自己。
    然而,这个notifier_call函数指针是什么东西? 赋值为哪个函数? 且看start_kernel() > tick_init() :
                
            clockevents_register_notifier(&tick_notifier);
   
    而tick_notifier的定义:
                
            static struct notifier_block tick_notifier = {
                    .notifier_call = tick_notify,
            };

    于是我们知道,tick_init()时已经为clockevents_chain的notifier_call指针赋值,这个值就是tick_notify
    函数:
                
            tick_notify():
                   
                switch(reason) {
                        case CLOCK_EVT_NOTIFY_ADD:
                                return tick_check_new_device(dev);
                        ...
                }
   
    而当初我们注册pit_clockevent和hpet_clockevent、lapic_clockevent时,就是指定了CLOCK_EVT_NOTIFY_ADD
    去调用clockevents_register_device的。 于是:

    tick_check_new_device() >  (to be continued)



资料:
Documentation/hrtimers/highres.txt和 http://www.linuxsymposium.org/2005/linuxsymposium_procv1.pdf中的一篇论文:
Hrtimers and Beyond: Transforming the Linux Time Subsystems

论坛徽章:
0
2 [报告]
发表于 2008-04-09 16:33 |只看该作者
原帖由 albcamus 于 2008-4-9 15:48 发表
关键是0号中断。  

麻烦之处是: HPET和PIT的代码都要分析, 而且还要涉及到 教新的 hrtimer和 dynamic tick,以及相关的clock event 模型。 等。


这里有一份带着很多问题的笔记:
================= ...

对时钟是真的不懂。
根据版主的线索先看看先,不过我现在中断都还没看完

论坛徽章:
0
3 [报告]
发表于 2008-04-09 20:18 |只看该作者

回复 #2 zx_wing 的帖子

我觉得不要一次引入这么多概念,得从最以前的模型开始一点一点加。毕竟,计算机系统也是这么发展起来的。一下子看这么多东西,还要理解,太困难了

论坛徽章:
0
4 [报告]
发表于 2008-04-09 20:28 |只看该作者
原帖由 bluesky_jxc 于 2008-4-9 20:18 发表
我觉得不要一次引入这么多概念,得从最以前的模型开始一点一点加。毕竟,计算机系统也是这么发展起来的。一下子看这么多东西,还要理解,太困难了

我这不是还在看中断吗,我不急,中断看懂后我再继续看时钟

论坛徽章:
0
5 [报告]
发表于 2008-07-13 10:55 |只看该作者
大约两个月前我把hrtimer相关代码看了一下,本想写篇文章的,但由于这样那样的事情耽搁了。老大还有没有兴趣讨论一下,我想说但又不知道从何说起
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP