Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1298820
  • 博文数量: 254
  • 博客积分: 1586
  • 博客等级: 上尉
  • 技术积分: 2295
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-15 16:38
个人简介

linux学习中

文章分类

全部博文(254)

文章存档

2016年(6)

2015年(2)

2014年(74)

2013年(93)

2012年(12)

2011年(2)

2010年(51)

2009年(14)

分类: LINUX

2013-12-10 10:37:48

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>在异常访问中关闭中断并加上自旋锁; 可延迟函数访问中关闭中断并加上自旋锁 ;中断的访问中加上自旋锁

其它的场景都可看作以上场景的组合
        如:异常,中断和可延迟函数中的数据访问保护。可看作中断和可延迟函数,中断和异常的组合。可同时使用相应的保护方式。
阅读(2839) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~