Linux内核中在自旋锁,信号量及中断禁止之间的选择

发布于 2022-10-15 04:09:57 字数 4415 浏览 17 评论 0

ULK3 第五章 中的 “在自旋锁,信号量及中断禁止之间的选择”粗略归纳了下,希望能与大家一起纸上谈兵。加深认识。

Linux内核中在自旋锁,信号量及中断禁止之间的选择

一.linux内核控制路径的三种执行环境:
        1>中断
                中断的顶半部分,也就是用request_irq注册的中断例程
                处中断上下文,不可睡眠
        2>可延迟函数(软中断及基于软中断实现的其它处理函数,如tasklet, 定时器等)
                被中断的顶半部分触发,并在稍后时间内执行的例程。
                处中断上下文,不可睡眠

                一般是:
                由open_softirq注册,在中断处理中由raise_softirq触发的函数。
                由tasklet_init初始化,在中断处理中由tasklet_schedule调度的函数。

        3>异常
                典型是系统调用(内核线程也算吧)。
                处进程上下文,可睡眠
               
中断,异常及可延迟函数之间对cpu的争夺:
        1>中断处理程序可以抢占其它中断处理程序
        2>中断处理程序可以抢占异常
        3>中断处理程序可以抢占可延迟函数

        4>中断处理程序在退出前触发可延迟函数。
        5>一个可延迟函数不能抢占中断处理程序。
        6>一个可延迟函数不能抢占另一个可延迟函数。
        7>相同类型的软中断可以并发的运行在多个cpu上
        8>相同类型的tasklet只能被串行的执行,不同类型的tasklet可以在几个cpu上并发执行。tasklet基于软中断而实现(可视为加入约束的软中断?)。
        9>软中断始终在触发它的同一个cpu上执行,tasklet也是。

        10>异常不能抢占中断,不能抢占可延迟函数,不能抢占异常(缺页不在考虑之中)

二.自信号旋锁,信号量及关中断的之间的……
        自旋锁:在竟争条件下,反复执行紧凑的循环指令,直到锁被释放。防止多cpu间的竟争。
        信号量:在竟争条件下,不允许内核控制路径继续进行,相应的进程被挂起。因此中断处理,和可延迟函数都不能使用信号量。
        关中断:禁用本地中断。关中断都是为了防止同一cpu下的中断抢占,关本地中断后,可延迟函数也被禁止了。

三.Linux内核中在自旋锁,信号量及中断禁止之间的选择

3.1仅异常时的数据访问保护
        1>单处理器:此时的CPU运行在内核态为用户进程提供服务。此竟争条件可通过信号量避免。
        2>多处理器:与单处理器环境时相同

        3>访问per-cpu变量时,要禁用抢占。
       
3.2仅中断时的数据访问保护
        单处理器
        1>只有一个中断的“上半部分”访问时,中断都相对自己串行地执行,无需同步。
        2>多个中断的“上半部分”访问时,要关中断。
        多处理器
        3>只有一个中断的“上半部分”访问时,中断都相对自己串行地执行,无需保护。
        4>多个中断可访问时,要关中断,并加上自旋锁。

3.3仅可延迟函数(软中断和tasklet)中的数据访问保护
        单处理器
        1>上不存在竞争问题
        多处理器
        2>软中断访问的数据使用自旋锁,防止多cpu竟争
        3>仅由一种tasklet访问的数据结构不需要保护
        4>被多种tasklet访问需要用自旋锁保护

3.4.异常和中断时的数据访问保护(只考虑一种中断与一种异常)
        单处理器
        1>在异常的访问中关闭中断;中断的访问中不需要保护
        多处理器
        2>在异常的访问中关闭本地中断,并加上自旋锁;中断的访问中加上自旋锁即可(可用紧循环和down_trylock代替自旋的功能)

3.5.异常和可延迟函数中的数据访问保护(只考虑一种异常与一种可延迟函数)
        单处理器
        1>在异常访问中关闭中断(禁止可延迟函数更合适);可延迟函数无需保护
        多处理器
        2>在异常访问中关闭中断(禁止可延迟函数更合适)并加上自旋锁;可延迟函数加上自旋锁

3.6.中断和可延迟函数中的数据访问保护(只考虑一种中断与一种可延迟函数)
        单处理器
        1>可延迟函数访问中关闭中断;中断的访问中不需要保护
        多处理器
        2>可延迟函数访问中关闭中断,并加上自旋锁;中断的访问中加上自旋锁

3.7.异常,中断和可延迟函数中的数据访问保护(只考虑一种中断一种可延迟函数一种异常)
        单处理器
        1>在异常访问中关闭中断; 可延迟函数访问中关闭中断 ;中断的访问中不需要保护
        多处理器
        2>在异常访问中关闭中断并加上自旋锁; 可延迟函数访问中关闭中断并加上自旋锁 ;中断的访问中加上自旋锁

其它的场景都可看作以上场景的组合
        如:异常,中断和可延迟函数中的数据访问保护。可看作中断和可延迟函数,中断和异常的组合。可同时使用相应的保护方式。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

木森分化 2022-10-22 04:09:57

感谢 LZ  分析

星星的轨迹 2022-10-22 04:09:57

本帖最后由 瀚海书香 于 2011-06-19 16:51 编辑

大家可以结合帖子http://bbs.chinaunix.net/viewthread.php?tid=2016217,加深一下对内核同步的理解。

此岸叶落 2022-10-22 04:09:57

不错,学习了

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文