Linux如何实现'队列自旋锁'?

时间:2016-01-18 11:40:21

标签: linux-kernel spinlock

根据文章http://www.phoronix.com/scan.php?page=news_item&px=queue-spinlocks-linux-4.2,从版本4.2开始,Linux内核将具有队列自旋锁。但是在4.4版中,我完成了spin_lock的实现,发现他们在kernel/locking/spinlock.c中实现了这样的自旋锁:

void __lockfunc __raw_##op##_lock(locktype##_t *lock)           \
{                                   \
    for (;;) {                          \
        preempt_disable();                  \
        if (likely(do_raw_##op##_trylock(lock)))        \
            break;                      \
        preempt_enable();                   \
                                \
        if (!(lock)->break_lock)                \
            (lock)->break_lock = 1;             \
        while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\
            arch_##op##_relax(&lock->raw_lock);     \
    }                               \
    (lock)->break_lock = 0;                     \
}                                   \

cmpxchg中有一个do_raw_spin_trylock,所以基本上它只是一个TATAS自旋锁。

但是,当我深入挖掘时,我发现do_raw_spin_lock将进入函数queued_spin_trylocklock变量的类型变为qspinlock。那么队列在哪里旋转?它隐藏在某个地方还是只是等待未来的实施?

要搜索源代码中的标识符,可以使用以下工具:http://lxr.free-electrons.com/

1 个答案:

答案 0 :(得分:1)

您正在查看的代码是#else:

#if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC)
/*
 * The __lock_function inlines are taken from
 * include/linux/spinlock_api_smp.h
 */
#else
...

默认情况下,在x86上,未定义CONFIG_GENERIC_LOCKBREAK,因此编译器不会编译该代码(即在#else子句中)。锁定ifdef的迷宫中有很多潜在的路径。确切的路径取决于您的体系结构以及您在.config中所做的任何自定义选择。