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>
This commit is contained in:
Ray Ni 2021-01-28 11:42:43 +08:00 committed by mergify[bot]
parent 6ffbb3581a
commit 62f2cf5784
2 changed files with 12 additions and 26 deletions

View File

@ -1,5 +1,5 @@
;------------------------------------------------------------------------------ ;
; Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
; Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
@ -125,19 +125,11 @@ SkipEnableExecuteDisable:
add edi, LockLocation
mov eax, NotVacantFlag
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
mov edi, esi
add edi, ApIndexLocation
mov ebx, 1
lock xadd dword [edi], ebx ; EBX = ApIndex++
inc ebx ; EBX is CpuNumber
mov edi, esi
add edi, StackSizeLocation

View File

@ -1,5 +1,5 @@
;------------------------------------------------------------------------------ ;
; Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
; Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
@ -161,18 +161,12 @@ LongModeStart:
add edi, LockLocation
mov rax, NotVacantFlag
TestLock:
xchg qword [edi], rax
cmp rax, NotVacantFlag
jz TestLock
mov edi, esi
add edi, ApIndexLocation
mov ebx, 1
lock xadd dword [edi], ebx ; EBX = ApIndex++
inc ebx ; EBX is CpuNumber
lea ecx, [esi + ApIndexLocation]
inc dword [ecx]
mov ebx, [ecx]
Releaselock:
mov rax, VacantFlag
xchg qword [edi], rax
; program stack
mov edi, esi
add edi, StackSizeLocation