[英]Why does spin_unlock_bh function enables preemption without calling the scheduler
我正在研究 kernel 代碼(版本 3.10.1)的自旋鎖代碼,但沒有理解一件事。
通過 function spin_lock_bh()
獲取自旋鎖時,它會繼續調用preempt_disable()
。 這與用於獲取的其他自旋鎖函數相同,例如spin_lock()
和spin_lock_irq()
。
但是當通過spin_unlock_bh()
釋放鎖時,它會調用preempt_enable_no_resched()
,它會跳過調用調度程序來搶占。 對於其他相應的釋放函數(如spin_unlock()
和spin_unlock_irq()
),情況並非如此。 他們調用常規的preempt_enable()
function 調用__schedule()
。
local_bh_disable()
preempt_count
計數器增加一個特定值, preempt_disable()
也將它增加1
。 這就是__raw_spin_lock_bh()
所做的。
preempt_enable()
function (從__raw_spin_unlock()
和__raw_spin_unlock_irq()
) 調用)調用preempt_check_resched()
。 但是,當搶占仍然被禁用時,無需嘗試安排。 它將在 function 出口的_local_bh_enable_ip()
內完成。
spin_release(&lock->dep_map, 1, _RET_IP_);
do_raw_spin_unlock(lock);
preempt_enable_no_resched();
\____barrier();
\____dec_preempt_count(); // <--- decrease counter, but we can't schedule here
local_bh_enable_ip();
\____sub_preempt_count() // <--- real disabling preemption
\____preempt_check_resched(); // <--- schedule
但是fe “IRQ”自旋鎖調用序列:
spin_release(&lock->dep_map, 1, _RET_IP_);
do_raw_spin_unlock(lock);
local_irq_enable();
preempt_enable();
\____barrier();
\____dec_preempt_count(); // <--- real disabling preemption
\____barrier();
\____preempt_check_resched(); // <--- schedule
總結一下:在 BH-spinlock 的情況下,它只是繞過preempt_check_resched()
因為它不是必需的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.