From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by mx.groups.io with SMTP id smtpd.web10.4288.1586498704986844776 for ; Thu, 09 Apr 2020 23:05:05 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.43, mailfrom: star.zeng@intel.com) IronPort-SDR: n4dRHrBDvsqFUAXhUNRyO1FfuMUEMMrolJNTrdnFh53FFqoqI4V1uUH4TTHkhS7tKhZ+W2qWO5 gGuy6FdLkSYg== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Apr 2020 23:05:04 -0700 IronPort-SDR: UiYu2DKt0G/d2L0WjbmgyoFTH22IMWhKyxDl7wIJzPQgLNvXjlHhJnwMdw5um9d61aRa1bGEif 1gavGJ8Yv7xw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,364,1580803200"; d="scan'208";a="252119976" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by orsmga003.jf.intel.com with ESMTP; 09 Apr 2020 23:05:04 -0700 Received: from fmsmsx157.amr.corp.intel.com (10.18.116.73) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 9 Apr 2020 23:05:03 -0700 Received: from shsmsx104.ccr.corp.intel.com (10.239.4.70) by FMSMSX157.amr.corp.intel.com (10.18.116.73) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 9 Apr 2020 23:05:03 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.138]) by SHSMSX104.ccr.corp.intel.com ([169.254.5.225]) with mapi id 14.03.0439.000; Fri, 10 Apr 2020 14:05:01 +0800 From: "Zeng, Star" To: "Dong, Eric" , Ray Ni , "devel@edk2.groups.io" CC: "Ni, Ray" Subject: Re: [PATCH v3] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performance of GetFreeToken() Thread-Topic: [PATCH v3] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performance of GetFreeToken() Thread-Index: AQHWDuMlkAeAsOwN30+1RWhfxtuQNahxJE+AgAC5xRA= Date: Fri, 10 Apr 2020 06:05:00 +0000 Message-ID: <0C09AFA07DD0434D9E2A0C6AEB0483104061F9FF@shsmsx102.ccr.corp.intel.com> References: <20200410025126.15460-1-niruiyu@users.noreply.github.com> In-Reply-To: Accept-Language: zh-CN, en-US 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: star.zeng@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Star Zeng > -----Original Message----- > From: Dong, Eric > Sent: Friday, April 10, 2020 11:00 AM > To: Ray Ni ; devel@edk2.groups.io > Cc: Ni, Ray ; Zeng, Star > Subject: RE: [PATCH v3] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the > performance of GetFreeToken() >=20 > Reviewed-by: Eric Dong >=20 > > -----Original Message----- > > From: Ray Ni [mailto:niruiyu@users.noreply.github.com] > > Sent: Friday, April 10, 2020 10:51 AM > > To: devel@edk2.groups.io > > Cc: Ni, Ray ; Dong, Eric ; > > Zeng, Star > > Subject: [PATCH v3] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the > performance > > of GetFreeToken() > > > > Today's GetFreeToken() runs at the algorithm complexity of O(n) where > > n is the size of the token list. > > > > 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). > > > > The improvement matters when some SMI code uses StartupThisAP() > > service for each of the AP such that the algorithm complexity becomes > > O(n) > > * O(m) where m is the AP count. > > > > As next steps, > > 1. PROCEDURE_TOKEN.Used field can be optimized out because all tokens > > before FirstFreeToken should have "Used" set while all after > > FirstFreeToken should have "Used" cleared. > > 2. ResetTokens() can be optimized to only reset tokens before > > FirstFreeToken. > > > > v2: add missing line in InitializeDataForMmMp. > > v3: update copyright year to 2020. > > > > Signed-off-by: Ray Ni > > Cc: Eric Dong > > Cc: Star Zeng > > --- > > UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 71 > ++++++++-------------- > > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 3 +- > > 2 files changed, 27 insertions(+), 47 deletions(-) > > > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c > > b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c > > index c285a70ebb..93cac5e4fa 100644 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c > > @@ -453,6 +453,11 @@ ResetTokens ( > > > > Link =3D GetNextNode (&gSmmCpuPrivate->TokenList, Link); > > } > > + > > + // > > + // Reset the FirstFreeToken to the beginning of token list upon exit= ing > SMI. > > + // > > + gSmmCpuPrivate->FirstFreeToken =3D GetFirstNode > > + (&gSmmCpuPrivate->TokenList); > > } > > > > /** > > @@ -1060,23 +1065,21 @@ IsTokenInUse ( > > /** > > Allocate buffer for the SPIN_LOCK and PROCEDURE_TOKEN. > > > > + @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; > > > > SpinLockSize =3D GetSpinLockProperties (); > > - ProcTokenSize =3D sizeof (PROCEDURE_TOKEN); > > > > TokenCountPerChunk =3D FixedPcdGet32 > > (PcdCpuSmmMpTokenCountPerChunk); > > ASSERT (TokenCountPerChunk !=3D 0); > > @@ -1092,49 +1095,22 @@ AllocateTokenBuffer ( > > SpinLockBuffer =3D AllocatePool (SpinLockSize * TokenCountPerChunk); > > ASSERT (SpinLockBuffer !=3D NULL); > > > > - ProcTokenBuffer =3D AllocatePool (ProcTokenSize * > > TokenCountPerChunk); > > - ASSERT (ProcTokenBuffer !=3D NULL); > > + ProcTokens =3D AllocatePool (sizeof (PROCEDURE_TOKEN) * > > + TokenCountPerChunk); ASSERT (ProcTokens !=3D NULL); > > > > for (Index =3D 0; Index < TokenCountPerChunk; Index++) { > > SpinLock =3D (SPIN_LOCK *)(SpinLockBuffer + SpinLockSize * Index); > > InitializeSpinLock (SpinLock); > > > > - 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; > > > > - InsertTailList (&gSmmCpuPrivate->TokenList, &ProcToken->Link); > > + InsertTailList (&gSmmCpuPrivate->TokenList, > > + &ProcTokens[Index].Link); > > } > > -} > > > > -/** > > - 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; > > } > > > > /** > > @@ -1154,12 +1130,15 @@ GetFreeToken ( { > > PROCEDURE_TOKEN *NewToken; > > > > - NewToken =3D FindFirstFreeToken (); > > - if (NewToken =3D=3D NULL) { > > - AllocateTokenBuffer (); > > - NewToken =3D FindFirstFreeToken (); > > + // > > + // If FirstFreeToken meets the end of token list, enlarge the token = list. > > + // 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); > > > > NewToken->Used =3D TRUE; > > NewToken->RunningApCount =3D RunningApsCount; @@ -1781,7 > +1760,7 @@ > > InitializeDataForMmMp ( > > > > InitializeListHead (&gSmmCpuPrivate->TokenList); > > > > - AllocateTokenBuffer (); > > + gSmmCpuPrivate->FirstFreeToken =3D AllocateTokenBuffer (); > > } > > > > /** > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > > index fe7e8b0323..c9b3b739f3 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 > > CPU. > > > > -Copyright (c) 2009 - 2019, Intel Corporation. All rights > > reserved.
> > +Copyright (c) 2009 - 2020, Intel Corporation. All rights > > +reserved.
> > Copyright (c) 2017, AMD Incorporated. All rights reserved.
> > > > SPDX-License-Identifier: BSD-2-Clause-Patent @@ -255,6 +255,7 @@ > > typedef struct { > > > > PROCEDURE_WRAPPER *ApWrapperFunc; > > LIST_ENTRY TokenList; > > + LIST_ENTRY *FirstFreeToken; > > } SMM_CPU_PRIVATE_DATA; > > > > extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate; > > -- > > 2.21.0.windows.1