buptzgl 发表于 2012-03-20 10:53

[请教大牛]spin_lock_irqsave之后用spin_unlock_irq解锁的疑问

我看到一段代码是这样的写的:
void function1()
{
    long flags;
    spin_lock_irqsave(&lock, flag);
    function2();
    spin_unlock_irqrestore(&lock, flag);
}

void function2()
{
   ...
   spin_unlock_irq(&lock);
   schedule();
   spin_lock_irq(&lock);
   ...
}

这里有一个疑问,就是在function2当中, schedule出去后,如果发生中断,中断的状态寄存器应该是会发生变化的,返回之后,在function1中,spin_unlock_irqrestore又恢复之前的中断状态,这样会不会有问题。麻烦牛牛们给解答一下,谢谢!

senioryzc 发表于 2012-03-20 11:25

第一, spinlock要求lock的是原子操作,所以你的代码不能schedule出去
第二,万一schedule出去了,运气好,schedule出去之后执行的代码里没有lock这个spinlock的,安全的schedule回来,操作系统会保证回到原点的时候,irq的状态也回到原点,比如通过保证进入中断和退出中断函数的时候,irq状态不变

buptzgl 发表于 2012-03-20 11:31

senioryzc,谢谢你的回答

不过我这个问题里头,schedule之前,spin_lock已经释放了,所以不存在你说的这个问题。

senioryzc 发表于 2012-03-20 11:43

这代码谁写的阿
spin_lock有好几种lock\unlock方式,lock和unlock需要配对使用的

非要乱用,然后乱用之后会出现什么问题,为什么会出现这个问题,都知道,那......还要知道什么?

buptzgl 发表于 2012-03-20 12:03

这段代码是一个同事写的,我觉得这样用可能有问题,但是针对这块也没有深入研究过,所以特来求教

这个问题的关键就是spin_lock_irqsave(&lock, flag)中关了中断,保存了中断状态寄存器,但是中间function2()中又释放过spin_lock,而且打开了中断,在schedule过程中,有可能改变中断寄存器,那spin_unlock_irqrestore(&lock, flag)之后,恢复寄存器状态之后,这时中断状态寄存器不就不对了吗?

azfa123 发表于 2012-03-20 14:30

参考:http://bbs.chinaunix.net/thread-3677074-3-1.html
24楼疑问、28楼、52楼解答。

个人认为自己写代码不要那么“飘逸”,或者依葫芦画瓢也要知其所以然。

buptzgl 发表于 2012-03-20 14:55

azfa123 大牛的回答也很飘逸啊,受教了,以后还要跟各位大牛多学习!谢谢

azfa123 发表于 2012-03-20 16:12

惭愧,本人也是初级菜鸟。

onlyxuyang 发表于 2012-03-21 22:18

...我觉得关着中断schedule是不太可能的事情......

魔血染青天 发表于 2014-11-30 11:24

这段code是有问题的

在smp的环境下

void function1()
{
    long flags;
    // 中断处理函数或许也会获取这个lock,不关闭中断的话,本cpu就有可能死锁
    spin_lock_irqsave(&lock, flag);
    function2();
    spin_unlock_irqrestore(&lock, flag);
}

void function2()
{
   ...
   // function1关闭中断,至少说明中断处理函数和function1有资源访问冲突
   // 这里解锁,打开中断的话,要小心才是
   spin_unlock_irq(&lock);
   schedule();
   spin_lock_irq(&lock);
   ...
}
页: [1]
查看完整版本: [请教大牛]spin_lock_irqsave之后用spin_unlock_irq解锁的疑问