V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
letianqiu
V2EX  ›  程序员

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

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

    发现大部分资料都是介绍如何使用 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 的情况下只需要重设一下硬件状态
    包内容的处理可以慢慢来,正常加锁就行,不必担心被打断
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1018 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 22:12 · PVG 06:12 · LAX 14:12 · JFK 17:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.