From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga06.intel.com (mga06.intel.com []) by mx.groups.io with SMTP id smtpd.web09.5115.1612511895936364606 for ; Thu, 04 Feb 2021 23:58:19 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: ray.ni@intel.com) IronPort-SDR: +5namewpFYec1H/ZhrjAs6clYSRUAodL5GahuBe1bMzKOxOsuBeGbeWhxFFPTR/R3gU4EA+0/K 8yfee2y4Ofjw== X-IronPort-AV: E=McAfee;i="6000,8403,9885"; a="242902264" X-IronPort-AV: E=Sophos;i="5.81,154,1610438400"; d="scan'208";a="242902264" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Feb 2021 23:58:18 -0800 IronPort-SDR: Rzth0/6qPp7j6rJVQXugoIR2IhBbV8jTOzbz/mvbaHLXuG+c1IBxaQ/K7F2LwIJQ7hzNA02ypj Kg60KfSho40A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,154,1610438400"; d="scan'208";a="434322790" Received: from ray-dev.ccr.corp.intel.com ([10.239.158.87]) by orsmga001.jf.intel.com with ESMTP; 04 Feb 2021 23:58:17 -0800 From: "Ni, Ray" To: devel@edk2.groups.io Cc: Laszlo Ersek , Eric Dong , Rahul1 Kumar Subject: [PATCH v2 3/3] UefiCpuPkg/MpInitLib: Use XADD to avoid lock acquire/release Date: Fri, 5 Feb 2021 15:58:10 +0800 Message-Id: <20210205075810.981-4-ray.ni@intel.com> X-Mailer: git-send-email 2.27.0.windows.1 In-Reply-To: <20210205075810.981-1-ray.ni@intel.com> References: <20210205075810.981-1-ray.ni@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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 Cc: Laszlo Ersek Cc: Eric Dong Cc: Rahul1 Kumar --- .../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/Li= brary/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: =0D ; AP init=0D mov edi, esi=0D - add edi, MP_CPU_EXCHANGE_INFO_FIELD (Lock)=0D - mov eax, NotVacantFlag=0D -=0D -TestLock:=0D - xchg [edi], eax=0D - cmp eax, NotVacantFlag=0D - jz TestLock=0D -=0D - mov ecx, esi=0D - add ecx, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)=0D - inc dword [ecx]=0D - mov ebx, [ecx]=0D -=0D -Releaselock:=0D - mov eax, VacantFlag=0D - xchg [edi], eax=0D + add edi, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)=0D + mov ebx, 1=0D + lock xadd dword [edi], ebx ; EBX =3D ApIndex++=0D + inc ebx ; EBX is CpuNumber=0D =0D mov edi, esi=0D add edi, MP_CPU_EXCHANGE_INFO_FIELD (StackSize)=0D diff --git a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc b/UefiCpuPkg/Library/Mp= InitLib/MpEqu.inc index 46c2b5c116..2e9368a374 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc +++ b/UefiCpuPkg/Library/MpInitLib/MpEqu.inc @@ -13,9 +13,6 @@ ;-------------------------------------------------------------------------= ------=0D %include "Nasm.inc"=0D =0D -VacantFlag equ 00h=0D -NotVacantFlag equ 0ffh=0D -=0D CPU_SWITCH_STATE_IDLE equ 0=0D CPU_SWITCH_STATE_STORED equ 1=0D CPU_SWITCH_STATE_LOADED equ 2=0D @@ -72,7 +69,6 @@ endstruc ; Equivalent NASM structure of MP_CPU_EXCHANGE_INFO=0D ;=0D struc MP_CPU_EXCHANGE_INFO=0D - .Lock: CTYPE_UINTN 1=0D .StackStart: CTYPE_UINTN 1=0D .StackSize: CTYPE_UINTN 1=0D .CFunction: CTYPE_UINTN 1=0D diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpIn= itLib/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;=0D =0D ExchangeInfo =3D CpuMpData->MpCpuExchangeInfo;=0D - ExchangeInfo->Lock =3D 0;=0D ExchangeInfo->StackStart =3D CpuMpData->Buffer;=0D ExchangeInfo->StackSize =3D CpuMpData->CpuApStackSize;=0D ExchangeInfo->BufferStart =3D CpuMpData->WakeupBuffer;=0D diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpIn= itLib/MpLib.h index 02652eaae1..0bd60388b1 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -1,7 +1,7 @@ /** @file=0D Common header file for MP Initialize Library.=0D =0D - Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
=0D + Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.
=0D Copyright (c) 2020, AMD Inc. All rights reserved.
=0D =0D SPDX-License-Identifier: BSD-2-Clause-Patent=0D @@ -190,7 +190,6 @@ typedef struct _CPU_MP_DATA CPU_MP_DATA; // into this structure are used in assembly code in this module=0D //=0D typedef struct {=0D - UINTN Lock;=0D UINTN StackStart;=0D UINTN StackSize;=0D UINTN CFunction;=0D diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Lib= rary/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: =0D ; AP init=0D mov edi, esi=0D - add edi, MP_CPU_EXCHANGE_INFO_FIELD (Lock)=0D - mov rax, NotVacantFlag=0D + add edi, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)=0D + mov ebx, 1=0D + lock xadd dword [edi], ebx ; EBX =3D ApIndex++=0D + inc ebx ; EBX is CpuNumber=0D =0D -TestLock:=0D - xchg qword [edi], rax=0D - cmp rax, NotVacantFlag=0D - jz TestLock=0D -=0D - lea ecx, [esi + MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)]=0D - inc dword [ecx]=0D - mov ebx, [ecx]=0D -=0D -Releaselock:=0D - mov rax, VacantFlag=0D - xchg qword [edi], rax=0D ; program stack=0D mov edi, esi=0D add edi, MP_CPU_EXCHANGE_INFO_FIELD (StackSize)=0D --=20 2.27.0.windows.1