From nobody Thu May 2 14:07:05 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+52531+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+52531+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1577162278; cv=none; d=zohomail.com; s=zohoarc; b=SSY05qoDLcbx4NxxXjXh74vTysvxfDiKOv7cSKqj11XwY3lO5BoLOxTDjkkHq/g3NHr2kOa+1pdgNGFABzhoFBcJzCqcuzJgWpgsEmXNEJzS5qGRrC9awDY8Si9lnli7vWDigtGleh8Q+hh/UYTRgcdMC15LwnN0jEgBZ5efACY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577162278; h=Content-Transfer-Encoding:Cc:Date:From:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To; bh=VFkfqViYtUassWQeuvckE+1ghOeWqJ5rHMYnviZxR7g=; b=iIbTRZo0iyPNNqfJQZBAeJmXGVBhEdc8Wvd/zZdi0VDPexadshYGn97YcRQCtL+Mj6Uf4lcdXM9smRyBYCyhfweKhECxo30yzxV+AehgKL5NYTqK41nnZNUEQgvc3IOJpwpKJKTv8l5IhdpvtnO4rKcbZS9+DXOGziHqTE7HNGI= 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+52531+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 157716227807766.2021855045067; Mon, 23 Dec 2019 20:37:58 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id j7wCYY1788612xHk70WUn0A9; Mon, 23 Dec 2019 20:37:57 -0800 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web12.1644.1577162276605349662 for ; Mon, 23 Dec 2019 20:37:57 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Dec 2019 20:37:55 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,350,1571727600"; d="scan'208";a="214429931" X-Received: from ydong10-desktop.ccr.corp.intel.com ([10.239.158.133]) by fmsmga008.fm.intel.com with ESMTP; 23 Dec 2019 20:37:54 -0800 From: "Dong, Eric" To: devel@edk2.groups.io Cc: Ray Ni , Laszlo Ersek Subject: [edk2-devel] [PATCH] UefiCpuPkg/PiSmmCpuDxeSmm: Pre-allocate PROCEDURE_TOKEN buffer Date: Tue, 24 Dec 2019 12:37:52 +0800 Message-Id: <20191224043752.696-1-eric.dong@intel.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,eric.dong@intel.com X-Gm-Message-State: e6bylWhVVAKt06YjGlx6o1GPx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1577162277; bh=FYVGMRa+muk2tnkIjhvLAApVIADIbS3Jtl//DZJt/ds=; h=Cc:Date:From:Reply-To:Subject:To; b=TIHCbvN/JGQ4+ry3t1iTkdyMrKbQqpO3qupDbLMGiti3OX5eFrOLa8q/Ta2fNA6Jwzb Ggb6UfCCpnFRbmnLYA1/hmv/9OBuVRSh/0B8tbpmdW1kxeWK7hsH4uBgzTw3ZBJYE+Z2M CSCiO4HbAXDzCHKlJOvFLioRB4jmda4YYxE= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2388 Token is new introduced by MM MP Protocol. Current logic allocate Token every time when need to use it. The logic caused SMI latency raised to very high. Update logic to allocate Token buffer at driver's entry point. Later use the token from the allocated token buffer. Only when all the buffer have been used, then need to allocate new buffer. Former change (9caaa79dd7e078ebb4012dde3b3d3a5d451df609) missed PROCEDURE_TOKEN part, this change covers it. Cc: Ray Ni Cc: Laszlo Ersek Signed-off-by: Eric Dong --- UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 200 ++++++++++++--------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 4 +- 2 files changed, 121 insertions(+), 83 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxe= Smm/MpService.c index 4808045f71..cb8d2be63c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -429,38 +429,29 @@ ReleaseToken ( =20 **/ VOID -FreeTokens ( +ResetTokens ( VOID ) { LIST_ENTRY *Link; PROCEDURE_TOKEN *ProcToken; - TOKEN_BUFFER *TokenBuf; =20 - // - // Only free the token buffer recorded in the OldTOkenBufList - // upon exiting SMI. Current token buffer stays allocated so - // next SMI doesn't need to re-allocate. - // - gSmmCpuPrivate->UsedTokenNum =3D 0; - - Link =3D GetFirstNode (&gSmmCpuPrivate->OldTokenBufList); - while (!IsNull (&gSmmCpuPrivate->OldTokenBufList, Link)) { - TokenBuf =3D TOKEN_BUFFER_FROM_LINK (Link); - - Link =3D RemoveEntryList (&TokenBuf->Link); - - FreePool (TokenBuf->Buffer); - FreePool (TokenBuf); - } - - while (!IsListEmpty (&gSmmCpuPrivate->TokenList)) { - Link =3D GetFirstNode (&gSmmCpuPrivate->TokenList); + Link =3D GetFirstNode (&gSmmCpuPrivate->TokenList); + while (!IsNull (&gSmmCpuPrivate->TokenList, Link)) { ProcToken =3D PROCEDURE_TOKEN_FROM_LINK (Link); =20 - RemoveEntryList (&ProcToken->Link); + ProcToken->RunningApCount =3D 0; + ProcToken->Used =3D FALSE; =20 - FreePool (ProcToken); + // + // Check the spinlock status and release it if not released yet. + // + if (!AcquireSpinLockOrFail(ProcToken->SpinLock)) { + DEBUG((DEBUG_ERROR, "Risk::SpinLock still not released!")); + } + ReleaseSpinLock (ProcToken->SpinLock); + + Link =3D GetNextNode (&gSmmCpuPrivate->TokenList, Link); } } =20 @@ -685,9 +676,9 @@ BSPHandler ( WaitForAllAPs (ApCount); =20 // - // Clean the tokens buffer. + // Reset the tokens buffer. // - FreeTokens (); + ResetTokens (); =20 // // Reset BspIndex to -1, meaning BSP has not been elected. @@ -1056,7 +1047,7 @@ IsTokenInUse ( while (!IsNull (&gSmmCpuPrivate->TokenList, Link)) { ProcToken =3D PROCEDURE_TOKEN_FROM_LINK (Link); =20 - if (ProcToken->SpinLock =3D=3D Token) { + if (ProcToken->Used && ProcToken->SpinLock =3D=3D Token) { return TRUE; } =20 @@ -1067,61 +1058,125 @@ IsTokenInUse ( } =20 /** - create token and save it to the maintain list. - - @param RunningApCount Input running AP count. - - @retval return the spin lock used as token. + Allocate buffer for the SPIN_LOCK and PROCEDURE_TOKEN. =20 **/ -PROCEDURE_TOKEN * -CreateToken ( - IN UINT32 RunningApCount +VOID +AllocateTokenBuffer ( + VOID ) { + UINTN SpinLockSize; + UINT32 TokenCountPerChunk; + UINTN ProcTokenSize; + UINTN Index; PROCEDURE_TOKEN *ProcToken; SPIN_LOCK *SpinLock; - UINTN SpinLockSize; TOKEN_BUFFER *TokenBuf; - UINT32 TokenCountPerChunk; + UINT8 *SpinLockBuffer; + UINT8 *ProcTokenBuffer; =20 SpinLockSize =3D GetSpinLockProperties (); + ProcTokenSize =3D sizeof (PROCEDURE_TOKEN); + TokenCountPerChunk =3D FixedPcdGet32 (PcdCpuSmmMpTokenCountPerChunk); + ASSERT (TokenCountPerChunk !=3D 0); + if (TokenCountPerChunk =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "PcdCpuSmmMpTokenCountPerChunk should not be Zero= !\n")); + CpuDeadLoop (); + } + DEBUG ((DEBUG_INFO, "CpuSmm: SpinLock Size =3D 0x%x, PcdCpuSmmMpTokenCou= ntPerChunk =3D 0x%x\n", SpinLockSize, TokenCountPerChunk)); =20 - if (gSmmCpuPrivate->UsedTokenNum =3D=3D TokenCountPerChunk) { - DEBUG ((DEBUG_VERBOSE, "CpuSmm: No free token buffer, allocate new buf= fer!\n")); + // + // Separate the Spin_lock and Proc_token because the alignment requires = by Spin_Lock. + // + SpinLockBuffer =3D AllocatePool (SpinLockSize * TokenCountPerChunk); + ASSERT (SpinLockBuffer !=3D NULL); =20 - // - // Record current token buffer for later free action usage. - // Current used token buffer not in this list. - // - TokenBuf =3D AllocatePool (sizeof (TOKEN_BUFFER)); - ASSERT (TokenBuf !=3D NULL); - TokenBuf->Signature =3D TOKEN_BUFFER_SIGNATURE; - TokenBuf->Buffer =3D gSmmCpuPrivate->CurrentTokenBuf; + TokenBuf =3D AllocatePool (sizeof (TOKEN_BUFFER)); + ASSERT (TokenBuf !=3D NULL); + TokenBuf->Signature =3D TOKEN_BUFFER_SIGNATURE; + TokenBuf->Buffer =3D SpinLockBuffer; + InsertTailList (&gSmmCpuPrivate->OldTokenBufList, &TokenBuf->Link); + + ProcTokenBuffer =3D AllocatePool (ProcTokenSize * TokenCountPerChunk); + ASSERT (ProcTokenBuffer !=3D NULL); + + TokenBuf =3D AllocatePool (sizeof (TOKEN_BUFFER)); + ASSERT (TokenBuf !=3D NULL); + TokenBuf->Signature =3D TOKEN_BUFFER_SIGNATURE; + TokenBuf->Buffer =3D ProcTokenBuffer; + InsertTailList (&gSmmCpuPrivate->OldTokenBufList, &TokenBuf->Link); + + for (Index =3D 0; Index < TokenCountPerChunk; Index++) { + SpinLock =3D (SPIN_LOCK *)(SpinLockBuffer + SpinLockSize * Index); + InitializeSpinLock (SpinLock); + + 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; + + InsertTailList (&gSmmCpuPrivate->TokenList, &ProcToken->Link); + } +} + +/** + Find first free token in the allocated token list. =20 - InsertTailList (&gSmmCpuPrivate->OldTokenBufList, &TokenBuf->Link); + @retval return the first free PROCEDURE_TOKEN. + +**/ +PROCEDURE_TOKEN * +FindFirstFreeToken ( + VOID + ) +{ + LIST_ENTRY *Link; + PROCEDURE_TOKEN *ProcToken; =20 - gSmmCpuPrivate->CurrentTokenBuf =3D AllocatePool (SpinLockSize * Token= CountPerChunk); - ASSERT (gSmmCpuPrivate->CurrentTokenBuf !=3D NULL); - gSmmCpuPrivate->UsedTokenNum =3D 0; + 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); } =20 - SpinLock =3D (SPIN_LOCK *)(gSmmCpuPrivate->CurrentTokenBuf + SpinLockSiz= e * gSmmCpuPrivate->UsedTokenNum); - gSmmCpuPrivate->UsedTokenNum++; + return NULL; +} =20 - InitializeSpinLock (SpinLock); - AcquireSpinLock (SpinLock); +/** + Get the free token. =20 - ProcToken =3D AllocatePool (sizeof (PROCEDURE_TOKEN)); - ASSERT (ProcToken !=3D NULL); - ProcToken->Signature =3D PROCEDURE_TOKEN_SIGNATURE; - ProcToken->SpinLock =3D SpinLock; - ProcToken->RunningApCount =3D RunningApCount; + If no free token, allocate new tokens then return the free one. =20 - InsertTailList (&gSmmCpuPrivate->TokenList, &ProcToken->Link); + @retval return the first free PROCEDURE_TOKEN. =20 - return ProcToken; +**/ +PROCEDURE_TOKEN * +GetFreeToken ( + IN UINT32 RunningApsCount + ) +{ + PROCEDURE_TOKEN *NewToken; + + NewToken =3D FindFirstFreeToken (); + if (NewToken =3D=3D NULL) { + AllocateTokenBuffer (); + NewToken =3D FindFirstFreeToken (); + } + ASSERT (NewToken !=3D NULL); + + NewToken->Used =3D TRUE; + NewToken->RunningApCount =3D RunningApsCount; + AcquireSpinLock (NewToken->SpinLock); + + return NewToken; } =20 /** @@ -1231,7 +1286,7 @@ InternalSmmStartupThisAp ( mSmmMpSyncData->CpuData[CpuIndex].Procedure =3D Procedure; mSmmMpSyncData->CpuData[CpuIndex].Parameter =3D ProcArguments; if (Token !=3D NULL) { - ProcToken=3D CreateToken (1); + ProcToken=3D GetFreeToken (1); mSmmMpSyncData->CpuData[CpuIndex].Token =3D ProcToken; *Token =3D (MM_COMPLETION)ProcToken->SpinLock; } @@ -1320,7 +1375,7 @@ InternalSmmStartupAllAPs ( } =20 if (Token !=3D NULL) { - ProcToken =3D CreateToken ((UINT32)mMaxNumberOfCpus); + ProcToken =3D GetFreeToken ((UINT32)mMaxNumberOfCpus); *Token =3D (MM_COMPLETION)ProcToken->SpinLock; } else { ProcToken =3D NULL; @@ -1732,28 +1787,13 @@ InitializeDataForMmMp ( VOID ) { - UINTN SpinLockSize; - UINT32 TokenCountPerChunk; - - SpinLockSize =3D GetSpinLockProperties (); - TokenCountPerChunk =3D FixedPcdGet32 (PcdCpuSmmMpTokenCountPerChunk); - ASSERT (TokenCountPerChunk !=3D 0); - if (TokenCountPerChunk =3D=3D 0) { - DEBUG ((DEBUG_ERROR, "PcdCpuSmmMpTokenCountPerChunk should not be Zero= !\n")); - CpuDeadLoop (); - } - DEBUG ((DEBUG_INFO, "CpuSmm: SpinLock Size =3D 0x%x, PcdCpuSmmMpTokenCou= ntPerChunk =3D 0x%x\n", SpinLockSize, TokenCountPerChunk)); - - gSmmCpuPrivate->CurrentTokenBuf =3D AllocatePool (SpinLockSize * TokenCo= untPerChunk); - ASSERT (gSmmCpuPrivate->CurrentTokenBuf !=3D NULL); - - gSmmCpuPrivate->UsedTokenNum =3D 0; - gSmmCpuPrivate->ApWrapperFunc =3D AllocatePool (sizeof (PROCEDURE_WRAPPE= R) * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus); ASSERT (gSmmCpuPrivate->ApWrapperFunc !=3D NULL); =20 InitializeListHead (&gSmmCpuPrivate->TokenList); InitializeListHead (&gSmmCpuPrivate->OldTokenBufList); + + AllocateTokenBuffer (); } =20 /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmC= puDxeSmm/PiSmmCpuDxeSmm.h index 5c98494e2c..e1c39583ad 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -214,6 +214,7 @@ typedef struct { =20 SPIN_LOCK *SpinLock; volatile UINT32 RunningApCount; + BOOLEAN Used; } PROCEDURE_TOKEN; =20 #define PROCEDURE_TOKEN_FROM_LINK(a) CR (a, PROCEDURE_TOKEN, Link, PROCED= URE_TOKEN_SIGNATURE) @@ -256,9 +257,6 @@ typedef struct { LIST_ENTRY TokenList; =20 LIST_ENTRY OldTokenBufList; - - UINT8 *CurrentTokenBuf; - UINT32 UsedTokenNum; // Only record tokens = used in CurrentTokenBuf. } SMM_CPU_PRIVATE_DATA; =20 extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate; --=20 2.23.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 (#52531): https://edk2.groups.io/g/devel/message/52531 Mute This Topic: https://groups.io/mt/69245252/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-