如何在Linux / ARM64中唤醒自旋锁?

时间:2015-08-28 17:07:57

标签: assembly linux-kernel arm64

在Linux内核中,arch_spin_lock()实现如下:

layer.cornerRadius

请注意,'wfe'指令将处理器置于低功耗模式,并等待设置事件寄存器。 ARMv8手册指定在清除PE的全局监视器时生成事件(第D1.17.1节)。这应该由解锁部分完成。但是让我们看一下arch_spin_unlock()部分:

static inline void arch_spin_lock(arch_spinlock_t *lock)
{
    unsigned int tmp;
    arch_spinlock_t lockval, newval;

    asm volatile(
    /* Atomically increment the next ticket. */
"   prfm    pstl1strm, %3\n"
"1: ldaxr   %w0, %3\n"
"   add %w1, %w0, %w5\n"
"   stxr    %w2, %w1, %3\n"
"   cbnz    %w2, 1b\n"
    /* Did we get the lock? */
"   eor %w1, %w0, %w0, ror #16\n"
"   cbz %w1, 3f\n"
    /*
     * No: spin on the owner. Send a local event to avoid missing an
     * unlock before the exclusive load.
     */
"   sevl\n"
"2: wfe\n"
"   ldaxrh  %w2, %4\n"
"   eor %w1, %w2, %w0, lsr #16\n"
"   cbnz    %w1, 2b\n"
    /* We got the lock. Critical section starts here. */
"3:"
    : "=&r" (lockval), "=&r" (newval), "=&r" (tmp), "+Q" (*lock)
    : "Q" (lock->owner), "I" (1 << TICKET_SHIFT)
    : "memory");
}

没有SEV !!那么,什么在这里唤醒锁定WFE?

PS:我一直在寻找任何ARM64组装教程,但没有提出任何建议。如果有人有任何建议会很棒。谢谢!

2 个答案:

答案 0 :(得分:2)

锁定时,行

" ldaxrh %w2, %4\n"

wfe执行锁的独占加载获取之后。如前一条评论中所述,这将标记全局监视器的锁定地址。

解锁代码在同一地址执行存储释放

" stlrh %w1, %0\n"

这将生成事件。这就是他们在锁定功能中使用加载获取的原因,而不是常规加载,以及解锁时不需要SEV的原因。

答案 1 :(得分:0)

即使存储位置已标记为独占,也会清除全局监视器事件。

参见状态转换图B2-5。存储到标记的地址将清除全局监视器事件,因为该事件生成事件。这将导致锁定wfe完成。