lock_buffer函数引发的思考

 42 static inline void lock_buffer(struct buffer_head * bh)
43 {
44 cli();
45 while (bh->b_lock)
46 sleep_on(&bh->b_wait);
47 bh->b_lock=1;
48 sti();
49 }

摘自kernel/blk_drv/ll_rw_blk.c

本篇文章主要讨论一下此函数有没有必要关闭中断。

Linux 0.11内核在内核态是不可抢占的,因为时钟中断的处理过程中发现被打断的执行序列正处在内核中,则不引发进程切换,也就是仍然返回原来的执行点继续执行。那是不是说,此函数可以不用禁中断呢?

以下的两点结论是针对内核态不可抢占的内核(2.6之前)

  假如一段代码里面操作到的数据只会被系统调用相关的内核代码访问到,那么这段代码就是原子的。因为不会有其他的执行序列改变这里操作的数据。

  假这些数据还会被中断过程访问到,那么这段代码就不是原子的了,因为中断随时可能发生,在中断中可能修改了这里的数据。中断包括时钟中断、软盘中断、硬盘中断等。

所以结论很明显了,bh->b_block会在硬盘或者软盘的中断操作中被清零,所以必须加上关中断的操作。

考虑如下情形:

  假如不加入cli的话,while执行时发现b_block为1,正准备睡眠,但是此时硬盘中断释放了此buffer,就造成该进程睡眠等待一个本没有被锁住的buffer,或许它永远都没机会醒过来啦。

对于2.6内核,假如临界区代码中存在系统调用或者中断过程会访问到的数据,那么此临界区代码应该在出入加上cli()/sti()。


转载于:https://www.cnblogs.com/gitclubs/archive/2012/02/23/2365300.html

你可能感兴趣的:(lock_buffer函数引发的思考)