]> git.proxmox.com Git - mirror_edk2.git/commit - UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
UefiCpuPkg/MpInitLib: Use XADD to avoid lock acquire/release
authorRay Ni <ray.ni@intel.com>
Thu, 28 Jan 2021 03:42:43 +0000 (11:42 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 26 Feb 2021 11:51:37 +0000 (11:51 +0000)
commit62f2cf57840e3b08122b6326b0ed9f4b25ce15d9
tree5562d04acc951974fbaaf5a90926854e2b3ee1cf
parent6ffbb3581ab7c25a35041bac03b760af54f852bf
UefiCpuPkg/MpInitLib: Use XADD to avoid lock acquire/release

When AP firstly wakes up, MpFuncs.nasm contains below logic to assign
an unique ApIndex to each AP according to who comes first:
---ASM---
TestLock:
    xchg       [edi], eax
    cmp        eax, NotVacantFlag
    jz         TestLock

    mov        ecx, esi
    add        ecx, ApIndexLocation
    inc        dword [ecx]
    mov        ebx, [ecx]

Releaselock:
    mov        eax, VacantFlag
    xchg       [edi], eax
---ASM END---

"lock inc" cannot be used to increase ApIndex because not only the
global ApIndex should be increased, but also the result should be
stored to a local general purpose register EBX.

This patch learns from the NASM implementation of
InternalSyncIncrement() to use "XADD" instruction which can increase
the global ApIndex and store the original ApIndex to EBX in one
instruction.

With this patch, OVMF when running in a 255 threads QEMU spends about
one second to wakeup all APs. Original implementation needs more than
10 seconds.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm