BKL(大内核锁)

BKL(大内核锁)是Linux内核中的一种全局自旋锁,用于SMP向细粒度锁过渡。它允许持有锁的任务睡眠但可能导致调度问题。BKL是递归的,并且在进程上下文中可用,不过对内核抢占有影响,现已被逐步淘汰。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 BKL(大内核锁)是一个全局自旋锁,使用它主要是为了方便实现从Linux最初的SMP过度到细粒度加锁机制。

 BKL的特性:

持有BKL的任务仍然可以睡眠 。因为当任务无法调度时,所加的锁会自动被抛弃;当任务被调度时,锁又会被重新获得。当然,并不是说,当任务持有BKL时,睡眠是安全的,紧急是可以这样做,因为睡眠不会造成任务死锁。

BKL是一种递归锁。一个进程可以多次请求一个锁,并不会像自旋锁那么产生死锁。

BKL可以在进程上下文中。

BKL是有害的。

在内核中不鼓励使用BKL。一个执行线程可以递归的请求锁lock_kernel(),但是释放锁时也必须调用同样次数的unlock_kernel()操作,在最后一个解锁操作完成之后,锁才会被释放。

 

  1. 在Kernel_lock.c(lib)中
  2. /*
  3.  * These are the BKL spinlocks - we try to be polite about preemption. 
  4.  * If SMP is not on (ie UP preemption), this all goes away because the
  5.  * _raw_spin_trylock() will always succeed.
  6.  */
  7. #ifdef CONFIG_PREEMPT
  8. static inline void __lock_kernel(void)
  9. {
  10.     preempt_disable();
  11.     if (unlikely(!_raw_spin_trylock(&kernel_flag))) {
  12.         /*
  13.          * If preemption was disabled even before this
  14.          * was called, there's nothing we can be polite
  15.          * about - just spin.
  16.          */
  17.         if (preempt_count() > 1) {
  18.             _raw_spin_lock(&kernel_flag);
  19.             return;
  20.         }
  21.         /*
  22.          * Otherwise, let's wait for the kernel lock
  23.          * with preemption enabled..
  24.          */
  25.         do {
  26.             preempt_enable();
  27.             while (spin_is_locked(&kernel_flag))
  28.                 cpu_relax();
  29.             preempt_disable();
  30.         } while (!_raw_spin_trylock(&kernel_flag));
  31.     }
  32. }
  33. #else
  34. /*
  35.  * Non-preemption case - just get the spinlock
  36.  */
  37. static inline void __lock_kernel(void)
  38. {
  39.     _raw_spin_lock(&kernel_flag);
  40. }
  41. #endif
  42. static inline void __unlock_kernel(void)
  43. {
  44.     /*
  45.      * the BKL is not covered by lockdep, so we open-code the
  46.      * unlocking sequence (and thus avoid the dep-chain ops):
  47.      */
  48.     _raw_spin_unlock(&kernel_flag);
  49.     preempt_enable();
  50. }
  51. /*
  52.  * Getting the big kernel lock.
  53.  *
  54.  * This cannot happen asynchronously, so we only need to
  55.  * worry about other CPU's.
  56.  */
  57. void __lockfunc lock_kernel(void)
  58. {
  59.     int depth = current->lock_depth+1;
  60.     if (likely(!depth))
  61.         __lock_kernel();
  62.     current->lock_depth = depth;
  63. }
  64. void __lockfunc unlock_kernel(void)
  65. {
  66.     BUG_ON(current->lock_depth < 0);
  67.     if (likely(--current->lock_depth < 0))
  68.         __unlock_kernel();
  69. }

BKL在被持有时同样会禁止内核抢占。多数情况下,BKL更像是保护代码而不是保护数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值