You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何spin_unlock_bh函数启用抢占却不调用调度器?

Spinlock Unlock Behavior in Linux Kernel 3.10.1: Why spin_unlock_bh() Uses preempt_enable_no_resched()

Great question—this digs into some really nuanced design choices around spinlocks and kernel context management. Let’s break down why this behavior exists:

First, let’s recap what each lock/unlock pair actually does:

  • spin_lock_bh() doesn’t just grab the spinlock—it also calls local_bh_disable() (disables softirqs like tasklets or bottom halves) and preempt_disable() (turns off kernel preemption). This is specifically for code paths that might be interrupted by softirqs, and need to block both preemption and softirq interference.
  • spin_lock() only disables preemption, while spin_lock_irq() disables both hardware interrupts and preemption.

Now, the key difference in their unlock counterparts:

  • For spin_unlock() and spin_unlock_irq(), using regular preempt_enable() makes sense because these paths return to a "normal" process context where immediate preemption is safe and desirable. If a higher-priority task is waiting, triggering __schedule() right away keeps the system responsive.
  • But spin_unlock_bh() has to handle a critical edge case: we might be returning from a softirq context (or just re-enabling softirqs in process context). Softirq contexts can’t be preempted—they run to completion without scheduling. When you call local_bh_enable() as part of spin_unlock_bh(), any pending softirqs will run immediately after the unlock. If we used regular preempt_enable() here, it could trigger a schedule right in the middle of softirq processing, which is unsafe and breaks kernel context rules.

Using preempt_enable_no_resched() solves this perfectly:

  • It marks preemption as allowed again, but skips the immediate call to __schedule().
  • The scheduler will still get a chance to run at the next valid scheduling point (like when returning to user space, or after any pending softirqs finish executing).
  • This ensures that softirqs get processed first, and we don’t introduce unexpected context switches in a context where they aren’t allowed.

To sum it up: spin_unlock_bh()’s design prioritizes safely re-enabling softirqs and deferring scheduling until a safe moment, whereas the other unlock functions can safely trigger scheduling immediately because they aren’t dealing with softirq context constraints.

内容的提问来源于stack exchange,提问作者Haris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:48:38