On 02/05/21 08:58, Ni, Ray wrote:
> When AP firstly wakes up, MpFuncs.nasm contains below logic to assign
> an unique ApIndex to each AP according to who comes first:
> ---NASM---
>     mov        edi, esi
>     add        edi, MP_CPU_EXCHANGE_INFO_FIELD (Lock)
>     mov        eax, NotVacantFlag
> 
> TestLock:
>     xchg       [edi], eax
>     cmp        eax, NotVacantFlag
>     jz         TestLock
> 
>     mov        ecx, esi
>     add        ecx, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)
>     inc        dword [ecx]
>     mov        ebx, [ecx]
> 
> Releaselock:
>     mov        eax, VacantFlag
>     xchg       [edi], eax
> ---NASM END---
> 
> "LOCK INC" cannot be used to increase MP_CPU_EXCHANGE_INFO.ApIndex
> because not only the MP_CPU_EXCHANGE_INFO.ApIndex should be
> increased, but also the result should be stored to a thread 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...@intel.com>
> Cc: Laszlo Ersek <ler...@redhat.com>
> Cc: Eric Dong <eric.d...@intel.com>
> Cc: Rahul1 Kumar <rahul1.ku...@intel.com>
> ---
>  .../Library/MpInitLib/Ia32/MpFuncs.nasm       | 20 ++++---------------
>  UefiCpuPkg/Library/MpInitLib/MpEqu.inc        |  4 ----
>  UefiCpuPkg/Library/MpInitLib/MpLib.c          |  1 -
>  UefiCpuPkg/Library/MpInitLib/MpLib.h          |  3 +--
>  UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 18 ++++-------------
>  5 files changed, 9 insertions(+), 37 deletions(-)
> 
> diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm 
> b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
> index 2f1b102717..7bd2415670 100644
> --- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
> +++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
> @@ -122,22 +122,10 @@ SkipEnableExecuteDisable:
>  
>      ; AP init
>      mov        edi, esi
> -    add        edi, MP_CPU_EXCHANGE_INFO_FIELD (Lock)
> -    mov        eax, NotVacantFlag
> -
> -TestLock:
> -    xchg       [edi], eax
> -    cmp        eax, NotVacantFlag
> -    jz         TestLock
> -
> -    mov        ecx, esi
> -    add        ecx, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)
> -    inc        dword [ecx]
> -    mov        ebx, [ecx]
> -
> -Releaselock:
> -    mov        eax, VacantFlag
> -    xchg       [edi], eax
> +    add        edi, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)
> +    mov        ebx, 1
> +    lock xadd  dword [edi], ebx                 ; EBX = ApIndex++
> +    inc        ebx                              ; EBX is CpuNumber
>  
>      mov        edi, esi
>      add        edi, MP_CPU_EXCHANGE_INFO_FIELD (StackSize)
> diff --git a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc 
> b/UefiCpuPkg/Library/MpInitLib/MpEqu.inc
> index 46c2b5c116..2e9368a374 100644
> --- a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc
> +++ b/UefiCpuPkg/Library/MpInitLib/MpEqu.inc
> @@ -13,9 +13,6 @@
>  
> ;-------------------------------------------------------------------------------
>  %include "Nasm.inc"
>  
> -VacantFlag                    equ        00h
> -NotVacantFlag                 equ        0ffh
> -
>  CPU_SWITCH_STATE_IDLE         equ        0
>  CPU_SWITCH_STATE_STORED       equ        1
>  CPU_SWITCH_STATE_LOADED       equ        2
> @@ -72,7 +69,6 @@ endstruc
>  ; Equivalent NASM structure of MP_CPU_EXCHANGE_INFO
>  ;
>  struc MP_CPU_EXCHANGE_INFO
> -  .Lock:                         CTYPE_UINTN 1
>    .StackStart:                   CTYPE_UINTN 1
>    .StackSize:                    CTYPE_UINTN 1
>    .CFunction:                    CTYPE_UINTN 1
> diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c 
> b/UefiCpuPkg/Library/MpInitLib/MpLib.c
> index 2568986d8c..5040053dad 100644
> --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
> +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
> @@ -1006,7 +1006,6 @@ FillExchangeInfoData (
>    IA32_CR4                         Cr4;
>  
>    ExchangeInfo                  = CpuMpData->MpCpuExchangeInfo;
> -  ExchangeInfo->Lock            = 0;
>    ExchangeInfo->StackStart      = CpuMpData->Buffer;
>    ExchangeInfo->StackSize       = CpuMpData->CpuApStackSize;
>    ExchangeInfo->BufferStart     = CpuMpData->WakeupBuffer;
> diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h 
> b/UefiCpuPkg/Library/MpInitLib/MpLib.h
> index 02652eaae1..0bd60388b1 100644
> --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
> +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
> @@ -1,7 +1,7 @@
>  /** @file
>    Common header file for MP Initialize Library.
>  
> -  Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
>    Copyright (c) 2020, AMD Inc. All rights reserved.<BR>
>  
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> @@ -190,7 +190,6 @@ typedef struct _CPU_MP_DATA  CPU_MP_DATA;
>  // into this structure are used in assembly code in this module
>  //
>  typedef struct {
> -  UINTN                 Lock;
>    UINTN                 StackStart;
>    UINTN                 StackSize;
>    UINTN                 CFunction;
> diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm 
> b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
> index bf7faaf60b..50df802d1f 100644
> --- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
> +++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
> @@ -158,21 +158,11 @@ LongModeStart:
>  
>      ; AP init
>      mov        edi, esi
> -    add        edi, MP_CPU_EXCHANGE_INFO_FIELD (Lock)
> -    mov        rax, NotVacantFlag
> +    add        edi, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)
> +    mov        ebx, 1
> +    lock xadd  dword [edi], ebx                 ; EBX = ApIndex++
> +    inc        ebx                              ; EBX is CpuNumber
>  
> -TestLock:
> -    xchg       qword [edi], rax
> -    cmp        rax, NotVacantFlag
> -    jz         TestLock
> -
> -    lea        ecx, [esi + MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)]
> -    inc        dword [ecx]
> -    mov        ebx, [ecx]
> -
> -Releaselock:
> -    mov        rax, VacantFlag
> -    xchg       qword [edi], rax
>      ; program stack
>      mov        edi, esi
>      add        edi, MP_CPU_EXCHANGE_INFO_FIELD (StackSize)
> 

Reviewed-by: Laszlo Ersek <ler...@redhat.com>



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#71365): https://edk2.groups.io/g/devel/message/71365
Mute This Topic: https://groups.io/mt/80401294/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to