linux ARM 自旋锁中是否存在竞争条件?

Is there a race condition in the linux ARM spinlock?

这是 Linux 自旋锁的实现,来自 arch/arm/include/asm/spinlock.h

static inline void arch_spin_lock(arch_spinlock_t *lock)
{
    unsigned long tmp;
    u32 newval;
    arch_spinlock_t lockval;

    prefetchw(&lock->slock);
    __asm__ __volatile__(
"1: ldrex   %0, [%3]\n"
"   add %1, %0, %4\n"
"   strex   %2, %1, [%3]\n"
"   teq %2, #0\n"
"   bne 1b"
    : "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
    : "r" (&lock->slock), "I" (1 << TICKET_SHIFT)
    : "cc");

    while (lockval.tickets.next != lockval.tickets.owner) {
        wfe();
        lockval.tickets.owner = READ_ONCE(lock->tickets.owner);
    }

    smp_mb();
}

...

static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
    smp_mb();
    lock->tickets.owner++;
    dsb_sev();
}

我担心的是 arch_spin_lock 中的以下两行:

    while (lockval.tickets.next != lockval.tickets.owner) {
        wfe();

不是原子的。那么如果在这两行之间调用 arch_spin_unlock 呢?这意味着在函数 arch_spin_lockWFE 指令将是 运行 但 SEV 已经是 运行 并且不会再次是 运行 .所以在最坏的情况下 arch_spin_lock 会永远等待,或者直到发生一些不相关的事件。

这是正确的,还是我误解了什么?如果这只是理论上的问题,有没有办法避免这个问题?

我认为您遗漏了这段 WFE 文档:

If the Event Register is set, WFE clears it and returns immediately.

在"race"中你描述的WFE会被执行,但是return会立即执行,然后while循环会退出。