From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mx.groups.io with SMTP id smtpd.web10.1116.1586480919502133159 for ; Thu, 09 Apr 2020 18:08:39 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.65, mailfrom: eric.dong@intel.com) IronPort-SDR: dKAf7gzyOYxgiBdxI1KPkK/fgeQuQCcMzjBRx4yOMleHaHWb1zXkOdw7SN/5Z4AUln+sdoDqj3 8CPzZ3UdCA3w== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Apr 2020 18:08:39 -0700 IronPort-SDR: KObLHSskp/okzAJYlomQdu53YYW7heKNAtN8DU8BEJySsqP3TWZL39pdIM3S5lpaFHc+oilOYv 30ulZtlc2PAA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,364,1580803200"; d="scan'208";a="425727667" Received: from fmsmsx106.amr.corp.intel.com ([10.18.124.204]) by orsmga005.jf.intel.com with ESMTP; 09 Apr 2020 18:08:38 -0700 Received: from fmsmsx602.amr.corp.intel.com (10.18.126.82) by FMSMSX106.amr.corp.intel.com (10.18.124.204) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 9 Apr 2020 18:08:38 -0700 Received: from fmsmsx602.amr.corp.intel.com (10.18.126.82) by fmsmsx602.amr.corp.intel.com (10.18.126.82) 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 18:08:38 -0700 Received: from shsmsx101.ccr.corp.intel.com (10.239.4.153) by fmsmsx602.amr.corp.intel.com (10.18.126.82) 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 18:08:37 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.138]) by SHSMSX101.ccr.corp.intel.com ([169.254.1.129]) with mapi id 14.03.0439.000; Fri, 10 Apr 2020 09:08:35 +0800 From: "Dong, Eric" To: Ray Ni , "devel@edk2.groups.io" CC: "Ni, Ray" , "Zeng, Star" , "Dong, Eric" Subject: Re: [PATCH] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performance of GetFreeToken() Thread-Topic: [PATCH] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performance of GetFreeToken() Thread-Index: AQHWDqbUaptfhShYvEGyRRhPxWYHd6hxiPHw Date: Fri, 10 Apr 2020 01:08:34 +0000 Message-ID: References: <20200409194033.82256-1-niruiyu@users.noreply.github.com> In-Reply-To: <20200409194033.82256-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, I think this patch misses the initialization for gSmmCpuPrivate->FirstFreeT= oken variable, right? Should add below code in InitializeDataForMmMp(), right? gSmmCpuPrivate->FirstFreeToken =3D AllocateTokenBuffer (); Also the copy right year should 2020 instead of 2021. Thanks, Eric -----Original Message----- From: Ray Ni =20 Sent: Friday, April 10, 2020 3:41 AM To: devel@edk2.groups.io Cc: Ni, Ray ; Dong, Eric ; Zeng, Sta= r Subject: [PATCH] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performance of GetF= reeToken() 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 | 71 ++++++++-------------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 3 +- 2 files changed, 27 insertions(+), 47 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxe= Smm/MpService.c index c285a70ebb..7a223410d7 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; diff --git a/UefiCpuPkg/Pi= SmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/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