簡體   English   中英

為什么 spin_unlock_bh function 在不調用調度程序的情況下啟用搶占

[英]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()內完成。

查看源代碼可以看到真正的“BH”自旋鎖調用序列是:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM