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_lock
中 WFE
指令将是 运行 但 SEV
已经是 运行 并且不会再次是 运行 .所以在最坏的情况下 arch_spin_lock
会永远等待,或者直到发生一些不相关的事件。
这是正确的,还是我误解了什么?如果这只是理论上的问题,有没有办法避免这个问题?
我认为您遗漏了这段 WFE 文档:
If the Event Register is set, WFE clears it and returns immediately.
在"race"中你描述的WFE
会被执行,但是return会立即执行,然后while
循环会退出。
这是 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_lock
中 WFE
指令将是 运行 但 SEV
已经是 运行 并且不会再次是 运行 .所以在最坏的情况下 arch_spin_lock
会永远等待,或者直到发生一些不相关的事件。
这是正确的,还是我误解了什么?如果这只是理论上的问题,有没有办法避免这个问题?
我认为您遗漏了这段 WFE 文档:
If the Event Register is set, WFE clears it and returns immediately.
在"race"中你描述的WFE
会被执行,但是return会立即执行,然后while
循环会退出。