From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by mx.groups.io with SMTP id smtpd.web12.2208.1586485541576106414 for ; Thu, 09 Apr 2020 19:25:41 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.151, mailfrom: eric.dong@intel.com) IronPort-SDR: UTmCR1TOpa9b0fwMOnLJlTP6TRF8gPgE4p6+YdysFEB3P6hddg7z7hDFp5kvoWzZ9z2Sp97GP1 GjNrcpFXoEeA== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Apr 2020 19:25:41 -0700 IronPort-SDR: uaThW2GLntDU+TJJP+W3h0OnuX11i1AUxUq0UFkSODLIsMESb3v7DgzBKvzrAPoVZ9R9KxzIvF 3cBB8x8Mb0YA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,364,1580803200"; d="scan'208";a="244471937" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by fmsmga008.fm.intel.com with ESMTP; 09 Apr 2020 19:25:41 -0700 Received: from fmsmsx607.amr.corp.intel.com (10.18.126.87) 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:25:41 -0700 Received: from fmsmsx607.amr.corp.intel.com (10.18.126.87) by fmsmsx607.amr.corp.intel.com (10.18.126.87) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Thu, 9 Apr 2020 19:25:40 -0700 Received: from shsmsx108.ccr.corp.intel.com (10.239.4.97) by fmsmsx607.amr.corp.intel.com (10.18.126.87) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.1713.5 via Frontend Transport; Thu, 9 Apr 2020 19:25:40 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.138]) by SHSMSX108.ccr.corp.intel.com ([169.254.8.7]) with mapi id 14.03.0439.000; Fri, 10 Apr 2020 10:25:38 +0800 From: "Dong, Eric" To: Ray Ni , "devel@edk2.groups.io" CC: "Ni, Ray" , "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: AQHWDtzt7VvtJoXZhk+bq3HJdW0pH6hxoLmg Date: Fri, 10 Apr 2020 02:25:37 +0000 Message-ID: References: <20200410020729.249960-1-niruiyu@users.noreply.github.com> In-Reply-To: <20200410020729.249960-1-niruiyu@users.noreply.github.com> Accept-Language: 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: eric.dong@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Ray, It still has copyright year issue. Should 2020, not 2021. Thanks, Eric -----Original Message----- From: Ray Ni =20 Sent: Friday, April 10, 2020 10:07 AM To: devel@edk2.groups.io Cc: Ni, Ray ; Dong, Eric ; Zeng, Sta= r Subject: [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performance of G= etFreeToken() 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 po= ints 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) wher= e m is the AP count. As next steps, 1. PROCEDURE_TOKEN.Used field can be optimized out because all tokens befor= e FirstFreeToken should have "Used" set while all after FirstFreeToken shou= ld have "Used" cleared. 2. ResetTokens() can be optimized to only reset tokens before FirstFreeToke= n. 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(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxe= Smm/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 @@ ResetTok= ens ( =20 Link =3D GetNextNode (&gSmmCpuPrivate->TokenList, Link); } + + // + // Reset the FirstFreeToken to the beginning of token list upon exiting = SMI. + // + gSmmCpuPrivate->FirstFreeToken =3D GetFirstNode=20 + (&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) *=20 + 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 * In= dex); - 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,=20 + &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 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=20 + (gSmmCpuPrivate->FirstFreeToken); gSmmCpuPrivate->FirstFreeToken =3D=20 + GetNextNode (&gSmmCpuPrivate->TokenList,=20 + gSmmCpuPrivate->FirstFreeToken); =20 NewToken->Used =3D TRUE; NewToken->RunningApCount =3D RunningApsCount; @@ -1781,7 +1760,7 @@ Init= ializeDataForMmMp ( =20 InitializeListHead (&gSmmCpuPrivate->TokenList); =20 - AllocateTokenBuffer (); + gSmmCpuPrivate->FirstFreeToken =3D AllocateTokenBuffer (); } =20 /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmC= puDxeSmm/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 CPU. =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 s= truct { =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