vonnyfly 发表于 2011-09-21 16:53

spin_lock_irqsave关中断后,为什么要再禁止抢占呢,不多余吗?

spin_lock_irqsave关中断后,为什么要再禁止抢占呢,不多余吗?static inline unsigned long __raw_spin_lock_irqsave(raw_spinlock_t *lock)
{
        unsigned long flags;

        local_irq_save(flags);
        preempt_disable();
        spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
。。。

SharkBones 发表于 2011-09-25 20:40

如果不禁止内核抢断,可能会有以下的情况发生(假设进程B比进程A具有更高的优先级):
进程A获得spinlock lock
进程B运行(抢占进程A)
进程B获取spinlock lock
由于进程B比进程A优先级高,所以进程B在进程A之前运行,而进程B需要进程A释放lock之后才能运行,于是,死锁:em02:

smalloc 发表于 2011-09-26 00:25

原因不是很多 但至少有一点 in_interrupt()统计包括preempt_count()
而local_irq_save不影响in_interrupt()的结果

smalloc 发表于 2011-09-26 00:32

还是那句话, 中断上下文不能睡眠
而不是在睡眠前不能调用spin_lock()--这是什么逻辑?

asuka2001 发表于 2011-09-26 14:40

求指教:获得spinlock的时候不会禁止抢占吗???

vonnyfly 发表于 2011-09-26 14:50

本帖最后由 vonnyfly 于 2011-09-26 15:03 编辑

回复 2# SharkBones
关中断跟禁止抢占之间没有关系么?
关掉中断之后,时钟肯定也关了,也就调度相关的代码就不会执行

我们知道,linux的进程调度时机有:
1、进程状态转换的时刻:进程终止、进程睡眠
2、当前的进程的时间片用完(current->counter=0)
3、设备驱动程序主动调用schedule
4、进程从中断、异常及系统调用返回用户态

这儿1、3不可能吧。2、4依赖时钟中断,我们关了本地中断(SP),那不就意味着不能抢占么?

zylthinking 发表于 2011-09-26 14:52

转:

所以,你最开始的疑问:“关中断只是屏蔽了中断,并没有阻止任务切换,高优先级的任务任然可以抢占CPU并访问临界区和共享变量啊”

关了中断,就禁止了抢占,如果当前任务也没有进行主动调度,当然系统中也就不会出现比当前优先级更高的任务进入就绪了,也就谈不上去“抢占CPU并访问临界区和共享变量”了。(作者这里说加了条件“如果当前任务也没有进行主动调度”,那如果当前任务进行了主动调度会怎么样?我认为,若是在临界区中进行了主动调度,那么后果就是提问的人说的:“关中断只是屏蔽了中断,并没有阻止任务切换,高优先级的任务任然可以抢占CPU并访问临界区和共享变量”。by imjacob)
由以下网址为证:http://www.gdjy.com.cn/xuexi/UNIX-XIUGAI/ch02/os0203.htm 中2.3.4为证。
上面是这么说的:

关 中 断 之 后, 任 何 外 部 事 件 都 不 能 打 扰 处 理 机 连 续 执 行 临 界 区 程 序。 如 果 临 界 区 程 序 本 身 并 不 包 含 使 它 的 进 程 转 变 为 封 锁 状 态 的 因 素, 那 么 这 种 方 法 就 能 保 证 临 界 区 作 为 一 个 整 体 执 行。 这 种 方 法 的 优 点 是 简 单、 可 靠, 但 是 它 也 有 一 定 的 局 限 性 和 若 干 不 足 之 处。

(1) 它 不 能 用 于 多 处 理 机 系 统。 其 原 因 是: 由 于 该 系 统 中 的 多 个 处 理 机 都 有 其 各 自 的 中 断 开 关, 因 此 一 个 处 理 机 并 不 能 阻 止 在 其 它 处 理 机 上 运 行 的 进 程 进 入 同 类 临 界 区。

(2) 在 临 界 区 中 如 果 包 含 有 使 执 行 它 的 进 程 有 可 能 进 入 封 锁 状 态 的 因 素, 则 也 不 能 使 用 这 种 方 法。 因 为 在 该 进 程 进 入 封 锁 状 态 后, 系 统 将 调 度 另 一 进 程 使 用 处 理 机, 如 果 需 要, 该 进 程 也 可 以 执 行 临 界 区 程 序, 不 会 受 到 任 何 阻 拦, 所 以 在 这 种 情 况 下, 开、 关 中 断 不 能 实 施 临 界 区 互 斥。

(3) 如 果 临 界 区 比 较 长, 则 本 法 会 降 低 中 断 响 应 速 度。

(4) 这 是 一 把 锁 处 理 各 类 临 界 区, 不 必 要 地 扩 大 了 互 斥 范 围。

asuka2001 发表于 2011-09-26 14:55

本帖最后由 asuka2001 于 2011-09-26 15:09 编辑

spin_lock_irqsave关中断后,为什么要再禁止抢占呢,不多余吗?

spin_lock_irqsave本身应该禁止了抢占吧,毕竟获取了自旋锁!

至于关中断和抢占,好象没啥联系,preempt_count里只有针对软中断,硬中断,和关闭抢占的计数器。

抢占的时机不仅仅和中断有关,比如解除自旋锁的时候也会恢复抢占,并且可能导致重新调度吧???

asuka2001 发表于 2011-09-26 15:01

还是那句话, 中断上下文不能睡眠
而不是在睡眠前不能调用spin_lock()--这是什么逻辑?

这个绕晕了,不太明白意思了。。。睡眠前spin_lock(),如果获取到了锁,肯定不应该睡眠;如果没获取到锁,那在自旋,执行不到后面去。
求解。。。

vonnyfly 发表于 2011-09-26 15:06

回复 8# asuka2001
关中断跟禁止抢占之间没有关系么?
关掉中断之后,时钟肯定也关了,也就调度相关的代码就不会执行

我们知道,linux的进程调度时机有:
1、进程状态转换的时刻:进程终止、进程睡眠
2、当前的进程的时间片用完(current->counter=0)
3、设备驱动程序主动调用schedule
4、进程从中断、异常及系统调用返回用户态

这儿1、3不可能吧。2、4依赖时钟中断,我们关了本地中断(SP),那不就意味着不能抢占么?可能是为了MP的需要?
页: [1] 2 3 4
查看完整版本: spin_lock_irqsave关中断后,为什么要再禁止抢占呢,不多余吗?