From nobody Fri May 17 16:11:40 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+57295+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+57295+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1586839007; cv=none; d=zohomail.com; s=zohoarc; b=XL97fC7Ev0esjsC+GrDKmqTM3uQyalLh8r5aaXw4AuxHM15aIbR5fbD4gCJYXhtK7DXTvdIscqDjy+o5zwiA1kXkp9RP2aJ7CtN7ydqelrqiVct9kSq38odYDlcQaq4+DWw3ELVyP4wk5CxWQb2rrs/l14isLQ+jSx+Kvpk8pZ0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1586839007; h=Content-Transfer-Encoding:Cc:Date:From:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To; bh=/Rg0bItDxlomYGwAEDEjgQZDGXpE+Nq5OXzpvGq3UYU=; b=NHs3jt1+kuXz5RjFRatt5KF+zDargFlAyqKSX4VZoEQHIJCbAMzsHxJzEP+7vGwWtJP7jv8ulQtxpSeyCKFq1tCrfCVl4Pu7QS/vfNYcDZYOq1vDS9irwKtlj930HyDz5ehD5pkRdep/SH/Dfzh1/FFJ2oE0Qmyj+Y5rWe2WbMA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+57295+1787277+3901457@groups.io Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1586839007096173.40904620093943; Mon, 13 Apr 2020 21:36:47 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id kx1YYY1788612xbzlXvE5tCv; Mon, 13 Apr 2020 21:36:46 -0700 X-Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web12.1959.1586484482561808626 for ; Thu, 09 Apr 2020 19:08:02 -0700 IronPort-SDR: wEBzbI5kqhs9nRy6Hrd4MTdcrg351jdCr/NYmXztRc8tqGZ7kORMz3gy6Ki0yjMw6WwiaYJbqE zWe86MFItp8A== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Apr 2020 19:08:02 -0700 IronPort-SDR: k8tW3eoW5O2YRondTNNZHdBm4KFmHpwi7JL7sw6PfonBRJqHBqrhhy9Jj9hmv5AaE48EhmOE+N kzfLAfHHxm2Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,364,1580803200"; d="scan'208";a="452237718" X-Received: from ray-dev.ccr.corp.intel.com ([10.239.158.43]) by fmsmga005.fm.intel.com with ESMTP; 09 Apr 2020 19:08:00 -0700 From: Ray Ni To: devel@edk2.groups.io Cc: Ray Ni , Eric Dong , Star Zeng Subject: [edk2-devel] [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performance of GetFreeToken() Date: Fri, 10 Apr 2020 10:07:29 +0800 Message-Id: <20200410020729.249960-1-niruiyu@users.noreply.github.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,niruiyu@users.noreply.github.com X-Gm-Message-State: rFMVUksvmBt2lhNWL1FuC24rx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1586839006; bh=B9p84986YvLId8XIaMEOYhu56IgzxxiIn8cm0zJCMfE=; h=Cc:Date:From:Reply-To:Subject:To; b=ATIrKCSbqjM2u5X0NpX66tcGoesnmXoW6FsVk1OZjOk2HtKPrMZPP6UoHB4WyRbpgxr zxZgC8xlfBcXvePBx2EyJi4AwfG3WylyyFC1qe8zJtIZ0oL/ZRo36zC9MP9KaxiP+XQGO A5EahGUvSpOKpSuDB9Gight3zCEDc413st4= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" 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. 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 @@ ResetTokens ( =20 Link =3D GetNextNode (&gSmmCpuPrivate->TokenList, Link); } + + // + // Reset the FirstFreeToken to the beginning of token list upon exiting = SMI. + // + gSmmCpuPrivate->FirstFreeToken =3D GetFirstNode (&gSmmCpuPrivate->TokenL= ist); } =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) * TokenCountPerChu= nk); + 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, &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 (gSmmCpuPrivate->FirstFreeToken); + gSmmCpuPrivate->FirstFreeToken =3D GetNextNode (&gSmmCpuPrivate->TokenLi= st, gSmmCpuPrivate->FirstFreeToken); =20 NewToken->Used =3D TRUE; NewToken->RunningApCount =3D RunningApsCount; @@ -1781,7 +1760,7 @@ InitializeDataForMmMp ( =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 struct { =20 PROCEDURE_WRAPPER *ApWrapperFunc; LIST_ENTRY TokenList; + LIST_ENTRY *FirstFreeToken; } SMM_CPU_PRIVATE_DATA; =20 extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate; --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#57295): https://edk2.groups.io/g/devel/message/57295 Mute This Topic: https://groups.io/mt/73004218/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-