Linux 如何实施 'queue spin lock'?

How Linux implement the 'queue spin lock'?

根据文章 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;                     \
}                                   \

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

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

在源代码中搜索标识符,这里是工具:http://lxr.free-electrons.com/

您正在查看的代码在#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.

中所做的任何自定义选择