spin_lock_bh作用:
1.保护临界区
2.禁止抢占
3.禁止软中断
在软中执行函数_do_softirq()中已经使用__local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET)来禁止软中断了,所以CPU上执行软中断是串行执行的。
软中断的执行:
1.irq_exit()退出时可能会执行softirq
2.softirq的内核线程
软中断和进程B共享链表A,软中断修改链表A,进程B读链表A。
情况1 未使用spin_lock保护链表A:
进程B读链表A的数据。硬件中断来的时候会中断进程B,当进程B正在读取链表A的时候,硬件中断来了,此时硬件中断退出时执行irq_exit,并调用了_do_softirq()执行软中断,修改了链表A,执行完成返回进程B,进程B再次读取链表A,可能访问到NULL的数据,出现崩溃。
情况2 使用spin_lock保护链表A:
spin_lock()无法禁止软中断执行。进程B先执行spin_lock(),进入临界区,读链表A,在临界区硬件中断到来,硬件中断执行完成,执行irq_exit(),然后执行_do_softirq()进入软中断执行,软中断处理函数也去执行spin_lock(),出现死锁。
情况3 使用spin_lock_bh保护链表A:
进程B先执行spin_lock_bh(),进入临界区,读链表A,在临界区硬件中断到来,硬件中断执行完成,执行irq_exit(), 然后执行in_interrupt()判断是否禁止了软中断,由于spin_lock_bh()禁止了软中断,所有不会去执行软中断函数,返回到进程B继续执行,正常。
总结:
1、spin_lock_bh()主要用于保护其他进程上下文访问软中断函数共享的变量。
2、在软中断中其实可以用spin_lock即可,可以不用spin_lock_bh