From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web12.2489.1586487021450994502 for ; Thu, 09 Apr 2020 19:50:21 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.88, mailfrom: ray.ni@intel.com) IronPort-SDR: EMVJnLw5PgCsrs7rzfBaKqU+aoPq1Lyvcvu94TZ15YVUWr7fA5dlYjO59U4w1vQZBDDxlHmXqX vHEmKti05Z9w== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Apr 2020 19:50:21 -0700 IronPort-SDR: Jef6aUlV8f4RijUmC/BBXWUjn4tsUyVi6BjtAYzhk8ovSV3qGSH7jIHhxAFP4M0R3tj0hcgtpw lSfBjUcmfwcA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,364,1580803200"; d="scan'208";a="276047543" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by fmsmga004.fm.intel.com with ESMTP; 09 Apr 2020 19:50:20 -0700 Received: from fmsmsx153.amr.corp.intel.com (10.18.125.6) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 9 Apr 2020 19:50:21 -0700 Received: from shsmsx154.ccr.corp.intel.com (10.239.6.54) by FMSMSX153.amr.corp.intel.com (10.18.125.6) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 9 Apr 2020 19:50:20 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.225]) by SHSMSX154.ccr.corp.intel.com ([169.254.7.214]) with mapi id 14.03.0439.000; Fri, 10 Apr 2020 10:50:18 +0800 From: "Ni, Ray" To: "Dong, Eric" , Ray Ni , "devel@edk2.groups.io" CC: "Zeng, Star" Subject: Re: [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performance of GetFreeToken() Thread-Topic: [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performance of GetFreeToken() Thread-Index: AQHWDtztEVa1wCKmDU68t5MO8oG6kqhxGs2AgACM2fA= Date: Fri, 10 Apr 2020 02:50:17 +0000 Message-ID: <734D49CCEBEEF84792F5B80ED585239D5C4E4334@SHSMSX104.ccr.corp.intel.com> References: <20200410020729.249960-1-niruiyu@users.noreply.github.com> In-Reply-To: Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: ray.ni@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable My bad. I thought it is 2021 now. let me send v3. > -----Original Message----- > From: Dong, Eric > Sent: Friday, April 10, 2020 10:26 AM > To: Ray Ni ; devel@edk2.groups.io > Cc: Ni, Ray ; Zeng, Star > Subject: RE: [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performanc= e of GetFreeToken() >=20 > Hi Ray, >=20 > It still has copyright year issue. Should 2020, not 2021. >=20 > Thanks, > Eric > -----Original Message----- > From: Ray Ni > Sent: Friday, April 10, 2020 10:07 AM > To: devel@edk2.groups.io > Cc: Ni, Ray ; Dong, Eric ; Zeng, S= tar > Subject: [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performance of= GetFreeToken() >=20 > Today's GetFreeToken() runs at the algorithm complexity of O(n) where n i= s the size of the token list. >=20 > The change introduces a new global variable FirstFreeToken and it always = points to the first free token. So the algorithm > complexity of GetFreeToken() decreases from O(n) to O(1). >=20 > The improvement matters when some SMI code uses StartupThisAP() service f= or each of the AP such that the algorithm > complexity becomes O(n) * O(m) where m is the AP count. >=20 > As next steps, > 1. PROCEDURE_TOKEN.Used field can be optimized out because all tokens bef= ore FirstFreeToken should have "Used" set while > all after FirstFreeToken should have "Used" cleared. > 2. ResetTokens() can be optimized to only reset tokens before FirstFreeTo= ken. >=20 > Signed-off-by: Ray Ni > Cc: Eric Dong > Cc: Star Zeng > --- > UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 73 ++++++++-------------- > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 3 +- > 2 files changed, 28 insertions(+), 48 deletions(-) >=20 > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuD= xeSmm/MpService.c > index c285a70ebb..b3f6c9e6a6 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c > @@ -1,7 +1,7 @@ > /** @file > SMM MP service implementation >=20 > -Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.
> +Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.
> Copyright (c) 2017, AMD Incorporated. All rights reserved.
>=20 > SPDX-License-Identifier: BSD-2-Clause-Patent @@ -453,6 +453,11 @@ ResetT= okens ( >=20 > Link =3D GetNextNode (&gSmmCpuPrivate->TokenList, Link); > } > + > + // > + // Reset the FirstFreeToken to the beginning of token list upon exitin= g SMI. > + // > + gSmmCpuPrivate->FirstFreeToken =3D GetFirstNode > + (&gSmmCpuPrivate->TokenList); > } >=20 > /** > @@ -1060,23 +1065,21 @@ IsTokenInUse ( > /** > Allocate buffer for the SPIN_LOCK and PROCEDURE_TOKEN. >=20 > + @return First token of the token buffer. > **/ > -VOID > +LIST_ENTRY * > AllocateTokenBuffer ( > VOID > ) > { > UINTN SpinLockSize; > UINT32 TokenCountPerChunk; > - UINTN ProcTokenSize; > UINTN Index; > - PROCEDURE_TOKEN *ProcToken; > SPIN_LOCK *SpinLock; > UINT8 *SpinLockBuffer; > - UINT8 *ProcTokenBuffer; > + PROCEDURE_TOKEN *ProcTokens; >=20 > SpinLockSize =3D GetSpinLockProperties (); > - ProcTokenSize =3D sizeof (PROCEDURE_TOKEN); >=20 > TokenCountPerChunk =3D FixedPcdGet32 (PcdCpuSmmMpTokenCountPerChunk); > ASSERT (TokenCountPerChunk !=3D 0); > @@ -1092,49 +1095,22 @@ AllocateTokenBuffer ( > SpinLockBuffer =3D AllocatePool (SpinLockSize * TokenCountPerChunk); > ASSERT (SpinLockBuffer !=3D NULL); >=20 > - ProcTokenBuffer =3D AllocatePool (ProcTokenSize * TokenCountPerChunk); > - ASSERT (ProcTokenBuffer !=3D NULL); > + ProcTokens =3D AllocatePool (sizeof (PROCEDURE_TOKEN) * > + TokenCountPerChunk); ASSERT (ProcTokens !=3D NULL); >=20 > for (Index =3D 0; Index < TokenCountPerChunk; Index++) { > SpinLock =3D (SPIN_LOCK *)(SpinLockBuffer + SpinLockSize * Index); > InitializeSpinLock (SpinLock); >=20 > - ProcToken =3D (PROCEDURE_TOKEN *)(ProcTokenBuffer + ProcTokenSize * = Index); > - ProcToken->Signature =3D PROCEDURE_TOKEN_SIGNATURE; > - ProcToken->SpinLock =3D SpinLock; > - ProcToken->Used =3D FALSE; > - ProcToken->RunningApCount =3D 0; > + ProcTokens[Index].Signature =3D PROCEDURE_TOKEN_SIGNATURE; > + ProcTokens[Index].SpinLock =3D SpinLock; > + ProcTokens[Index].Used =3D FALSE; > + ProcTokens[Index].RunningApCount =3D 0; >=20 > - InsertTailList (&gSmmCpuPrivate->TokenList, &ProcToken->Link); > + InsertTailList (&gSmmCpuPrivate->TokenList, > + &ProcTokens[Index].Link); > } > -} >=20 > -/** > - Find first free token in the allocated token list. > - > - @retval return the first free PROCEDURE_TOKEN. > - > -**/ > -PROCEDURE_TOKEN * > -FindFirstFreeToken ( > - VOID > - ) > -{ > - LIST_ENTRY *Link; > - PROCEDURE_TOKEN *ProcToken; > - > - Link =3D GetFirstNode (&gSmmCpuPrivate->TokenList); > - while (!IsNull (&gSmmCpuPrivate->TokenList, Link)) { > - ProcToken =3D PROCEDURE_TOKEN_FROM_LINK (Link); > - > - if (!ProcToken->Used) { > - return ProcToken; > - } > - > - Link =3D GetNextNode (&gSmmCpuPrivate->TokenList, Link); > - } > - > - return NULL; > + return &ProcTokens[0].Link; > } >=20 > /** > @@ -1154,12 +1130,15 @@ GetFreeToken ( > { > PROCEDURE_TOKEN *NewToken; >=20 > - NewToken =3D FindFirstFreeToken (); > - if (NewToken =3D=3D NULL) { > - AllocateTokenBuffer (); > - NewToken =3D FindFirstFreeToken (); > + // > + // If FirstFreeToken meets the end of token list, enlarge the token li= st. > + // Set FirstFreeToken to the first free token. > + // > + if (gSmmCpuPrivate->FirstFreeToken =3D=3D &gSmmCpuPrivate->TokenList) = { > + gSmmCpuPrivate->FirstFreeToken =3D AllocateTokenBuffer (); > } > - ASSERT (NewToken !=3D NULL); > + NewToken =3D PROCEDURE_TOKEN_FROM_LINK > + (gSmmCpuPrivate->FirstFreeToken); gSmmCpuPrivate->FirstFreeToken =3D > + GetNextNode (&gSmmCpuPrivate->TokenList, > + gSmmCpuPrivate->FirstFreeToken); >=20 > NewToken->Used =3D TRUE; > NewToken->RunningApCount =3D RunningApsCount; @@ -1781,7 +1760,7 @@ In= itializeDataForMmMp ( >=20 > InitializeListHead (&gSmmCpuPrivate->TokenList); >=20 > - AllocateTokenBuffer (); > + gSmmCpuPrivate->FirstFreeToken =3D AllocateTokenBuffer (); > } >=20 > /** > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSm= mCpuDxeSmm/PiSmmCpuDxeSmm.h > index fe7e8b0323..17f4bd34fa 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > @@ -1,7 +1,7 @@ > /** @file > Agent Module to load other modules to deploy SMM Entry Vector for X86 CP= U. >=20 > -Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
> +Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.
> Copyright (c) 2017, AMD Incorporated. All rights reserved.
>=20 > SPDX-License-Identifier: BSD-2-Clause-Patent @@ -255,6 +255,7 @@ typedef= struct { >=20 > PROCEDURE_WRAPPER *ApWrapperFunc; > LIST_ENTRY TokenList; > + LIST_ENTRY *FirstFreeToken; > } SMM_CPU_PRIVATE_DATA; >=20 > extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate; > -- > 2.21.0.windows.1