操作系统是如何实现 interrupt handler 的 bottom halves 的? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
letianqiu
V2EX    程序员

操作系统是如何实现 interrupt handler 的 bottom halves 的?

  •  
  •   letianqiu 2018-08-04 17:48:29 +08:00 3522 次点击
    这是一个创建于 2712 天前的主题,其中的信息可能已经有所发展或是发生改变。

    发现大部分资料都是介绍如何使用 Linux 下的 softirq,tasklet,workqueue 的。并没有解释这些机制究竟是怎么实现 bottom halves 的。感到很疑惑。我的理解:中断发生以后,陷入内核,执行中断处理程序,中断处理程序返回之后,CPU 应该恢复到被中断之前的状态,继续执行。如果是这样的话,我不能理解 bottom halves 什么时候能够得到执行。

    11 条回复    2018-08-05 14:30:55 +08:00
    misaka19000
        1
    misaka19000  
       2018-08-04 18:08:07 +08:00
    我感觉你是不是把中断处理和多进程切换搞混了?
    zchpeter
        2
    zchpeter  
       2018-08-04 21:12:41 +08:00 via Android
    只要 cpu 能把现在的状态记录下来,运行完 interrupt handler 之后,恢复原状态就好。trick 就是把状态(运行到的指令的行数,local variables,etc) 放在 stack 中,执行完 interrupt handler 再出栈。
    本质和 function call 类似
    letianqiu
        3
    letianqiu  
    OP
       2018-08-04 21:19:58 +08:00
    @zchpeter 可能我的问题描述不清楚。我不理解的是 bottom halves 是怎么执行的。你描述的就是我说的 top havles。如果 top halves 直接返回到原来被中断的地方执行,那么被 defer 到 bottom halves 里的部分又是怎么能够得到执行的。
    zchpeter
        4
    zchpeter  
       2018-08-04 21:36:39 +08:00 via Android
    @letianqiu https://notes.shichao.io/lkd/ch8/
    这篇讲的比较好。是我理解错了,之前不知道 top halves 和 bottom halves 的区别。其实 bottom halves 被执行的时间点不固定。很多情况都是 top half 被执行后,立刻执行 bottom half。主要要理解这样做的原因: top half 中,interrupt 都被禁了,所以要尽快执行完。而 bottom half 中是可以被 interrupt 的
    letianqiu
        5
    letianqiu  
    OP
       2018-08-04 22:01:50 +08:00
    @zchpeter 这篇就是 Robert Love 的 Linux Kernel Development 3rd Edition。我看过,也明白这么做的原因,但是就是不理解具体的实现原理。直接看源码迷失了。Quora 上 Robert Love 有个回答提到 bottom halves 也是在 interrupt context 里执行的,这也是让我迷惑的地方。如果 top halves 直接返回到 process,就变成 process context 了,被 defer 的 bottom halves 怎么能够在 interrupt context 里执行呢。难道说 top halves 返回之后必定跳转到 bottom havles 里执行,然后从 bottom halves 里返回才是回到被中断的 process 里?
    ryd994
        6
    ryd994  
       2018-08-04 23:48:23 +08:00 via Android
    @letianqiu "The key is that they run with all interrupts enabled.".
    Quora 上的人说错了,或者你理解错了
    bottom half 也关中断的话,还要分开来干嘛。可能他说的只是 bottom half 继续处理中断数据的意思。
    lesteryu
        7
    lesteryu  
       2018-08-05 00:31:17 +08:00 via iPhone
    Linux 上是怎么做的不熟,但是 Windows 上是通过中断级别 (IRQL) 和 Deferred Procedure Call (DPC,近似于 bottom half) 实现的。DPC 在 IRQL 里的优先级比硬件中断低,比软件中断高,和线程调度共享一个中断级别。当 Windows 在高 IRQL 下执行完中断例程(近似于 top half)之后,会把 IRQL 降低到 DPC 级别,然后执行所有在 DPC queue 里的 bottom halves,最后再把 IRQL 降低到其他的比如 APC 和用户线程级别。
    letianqiu
        8
    letianqiu  
    OP
       2018-08-05 09:20:47 +08:00
    @ryd994 interrupt context 不是指关中断的情况,就是表示和并不是当前运行的 process 的 process context。我不理解的就是从 top halves 返回之后,究竟返回到什么地方。
    @lesteryu 是不是可以这么理解,windows 下,Deferred Procedure Call (bottom halves)也是由 scheduler 调度的,并且 priority 比普通的 process 高,所以可以得到优先调度。这样的话,top halves 完成后,就直接回到被中断的 process context 里,继续执行。
    ryd994
        9
    ryd994  
       2018-08-05 10:24:12 +08:00 via Android   1
    @letianqiu 处理中断的时候应该要关低级中断啊,而且 top half 严禁 block
    bottom half 是允许调度的,也就允许 block (实际上要看具体 bottom half 用的哪种)
    是比普通进程优先,但在其他 upper half 的下面
    letianqiu
        10
    letianqiu  
    OP
       2018-08-05 13:07:43 +08:00
    @ryd994 “处理中断的时候应该要关低级中断啊,而且 top half 严禁 block “ 我是理解的。如果 bottom halves 是被调度的话,我想我就明白了。我原来认为 bottom halves 和 top havles 一样,不是被调度的。
    ryd994
        11
    ryd994  
       2018-08-05 14:30:55 +08:00 via Android
    @letianqiu 就算不能调度也有意义
    因为可以开中断

    比如说网卡,如果中断关太久,缓冲不够就只能丢包
    网卡 tophalf 其实只要从缓冲里把数据取出,这个是不能被打断的
    用 dma 或者 napi 的情况下只需要重设一下硬件状态
    包内容的处理可以慢慢来,正常加锁就行,不必担心被打断
    关于 &nbp;   帮助文档     自助推广系统     博客     API     FAQ     Solana     3905 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 05:11 PVG 13:11 LAX 21:11 JFK 00:11
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86