From: "Laszlo Ersek" <lersek@redhat.com>
To: "Ni, Ray" <ray.ni@intel.com>, "Dong, Eric" <eric.dong@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Subject: Re: [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Pre-allocate PROCEDURE_TOKEN buffer
Date: Thu, 2 Jan 2020 16:12:13 +0100 [thread overview]
Message-ID: <53138ceb-61db-6e1d-0743-1ce81525e0fb@redhat.com> (raw)
In-Reply-To: <734D49CCEBEEF84792F5B80ED585239D5C3D17A0@SHSMSX104.ccr.corp.intel.com>
On 01/02/20 04:30, Ni, Ray wrote:
> Reviewed-by: Ray Ni <ray.ni@intel.com>
Eric, please go ahead with Ray's R-b.
Thanks
Laszlo
>
>> -----Original Message-----
>> From: Dong, Eric <eric.dong@intel.com>
>> Sent: Friday, December 27, 2019 3:49 PM
>> To: devel@edk2.groups.io
>> Cc: Ni, Ray <ray.ni@intel.com>; Laszlo Ersek <lersek@redhat.com>
>> Subject: [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Pre-allocate
>> PROCEDURE_TOKEN buffer
>>
>> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2388
>>
>> 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 <ray.ni@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Signed-off-by: Eric Dong <eric.dong@intel.com>
>> ---
>>
>> v2 changes:
>>
>> Remove the not used variable.
>>
>>
>> UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 190 ++++++++++++-------
>> --
>> UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 6 +-
>> 2 files changed, 109 insertions(+), 87 deletions(-)
>>
>> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
>> b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
>> index 4808045f71..870250b0c5 100644
>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
>> @@ -429,38 +429,29 @@ ReleaseToken (
>>
>>
>> **/
>>
>> VOID
>>
>> -FreeTokens (
>>
>> +ResetTokens (
>>
>> VOID
>>
>> )
>>
>> {
>>
>> LIST_ENTRY *Link;
>>
>> PROCEDURE_TOKEN *ProcToken;
>>
>> - TOKEN_BUFFER *TokenBuf;
>>
>>
>>
>> - //
>>
>> - // 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 = 0;
>>
>> -
>>
>> - Link = GetFirstNode (&gSmmCpuPrivate->OldTokenBufList);
>>
>> - while (!IsNull (&gSmmCpuPrivate->OldTokenBufList, Link)) {
>>
>> - TokenBuf = TOKEN_BUFFER_FROM_LINK (Link);
>>
>> -
>>
>> - Link = RemoveEntryList (&TokenBuf->Link);
>>
>> -
>>
>> - FreePool (TokenBuf->Buffer);
>>
>> - FreePool (TokenBuf);
>>
>> - }
>>
>> -
>>
>> - while (!IsListEmpty (&gSmmCpuPrivate->TokenList)) {
>>
>> - Link = GetFirstNode (&gSmmCpuPrivate->TokenList);
>>
>> + Link = GetFirstNode (&gSmmCpuPrivate->TokenList);
>>
>> + while (!IsNull (&gSmmCpuPrivate->TokenList, Link)) {
>>
>> ProcToken = PROCEDURE_TOKEN_FROM_LINK (Link);
>>
>>
>>
>> - RemoveEntryList (&ProcToken->Link);
>>
>> + ProcToken->RunningApCount = 0;
>>
>> + ProcToken->Used = FALSE;
>>
>> +
>>
>> + //
>>
>> + // 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);
>>
>>
>>
>> - FreePool (ProcToken);
>>
>> + Link = GetNextNode (&gSmmCpuPrivate->TokenList, Link);
>>
>> }
>>
>> }
>>
>>
>>
>> @@ -685,9 +676,9 @@ BSPHandler (
>> WaitForAllAPs (ApCount);
>>
>>
>>
>> //
>>
>> - // Clean the tokens buffer.
>>
>> + // Reset the tokens buffer.
>>
>> //
>>
>> - FreeTokens ();
>>
>> + ResetTokens ();
>>
>>
>>
>> //
>>
>> // Reset BspIndex to -1, meaning BSP has not been elected.
>>
>> @@ -1056,7 +1047,7 @@ IsTokenInUse (
>> while (!IsNull (&gSmmCpuPrivate->TokenList, Link)) {
>>
>> ProcToken = PROCEDURE_TOKEN_FROM_LINK (Link);
>>
>>
>>
>> - if (ProcToken->SpinLock == Token) {
>>
>> + if (ProcToken->Used && ProcToken->SpinLock == Token) {
>>
>> return TRUE;
>>
>> }
>>
>>
>>
>> @@ -1067,61 +1058,112 @@ IsTokenInUse (
>> }
>>
>>
>>
>> /**
>>
>> - 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.
>>
>>
>>
>> **/
>>
>> -PROCEDURE_TOKEN *
>>
>> -CreateToken (
>>
>> - IN UINT32 RunningApCount
>>
>> +VOID
>>
>> +AllocateTokenBuffer (
>>
>> + VOID
>>
>> )
>>
>> {
>>
>> - PROCEDURE_TOKEN *ProcToken;
>>
>> - SPIN_LOCK *SpinLock;
>>
>> UINTN SpinLockSize;
>>
>> - TOKEN_BUFFER *TokenBuf;
>>
>> UINT32 TokenCountPerChunk;
>>
>> + UINTN ProcTokenSize;
>>
>> + UINTN Index;
>>
>> + PROCEDURE_TOKEN *ProcToken;
>>
>> + SPIN_LOCK *SpinLock;
>>
>> + UINT8 *SpinLockBuffer;
>>
>> + UINT8 *ProcTokenBuffer;
>>
>>
>>
>> SpinLockSize = GetSpinLockProperties ();
>>
>> + ProcTokenSize = sizeof (PROCEDURE_TOKEN);
>>
>> +
>>
>> TokenCountPerChunk = FixedPcdGet32
>> (PcdCpuSmmMpTokenCountPerChunk);
>>
>> + ASSERT (TokenCountPerChunk != 0);
>>
>> + if (TokenCountPerChunk == 0) {
>>
>> + DEBUG ((DEBUG_ERROR, "PcdCpuSmmMpTokenCountPerChunk should
>> not be Zero!\n"));
>>
>> + CpuDeadLoop ();
>>
>> + }
>>
>> + DEBUG ((DEBUG_INFO, "CpuSmm: SpinLock Size = 0x%x,
>> PcdCpuSmmMpTokenCountPerChunk = 0x%x\n", SpinLockSize,
>> TokenCountPerChunk));
>>
>>
>>
>> - if (gSmmCpuPrivate->UsedTokenNum == TokenCountPerChunk) {
>>
>> - DEBUG ((DEBUG_VERBOSE, "CpuSmm: No free token buffer, allocate new
>> buffer!\n"));
>>
>> + //
>>
>> + // Separate the Spin_lock and Proc_token because the alignment requires
>> by Spin_Lock.
>>
>> + //
>>
>> + SpinLockBuffer = AllocatePool (SpinLockSize * TokenCountPerChunk);
>>
>> + ASSERT (SpinLockBuffer != NULL);
>>
>>
>>
>> - //
>>
>> - // Record current token buffer for later free action usage.
>>
>> - // Current used token buffer not in this list.
>>
>> - //
>>
>> - TokenBuf = AllocatePool (sizeof (TOKEN_BUFFER));
>>
>> - ASSERT (TokenBuf != NULL);
>>
>> - TokenBuf->Signature = TOKEN_BUFFER_SIGNATURE;
>>
>> - TokenBuf->Buffer = gSmmCpuPrivate->CurrentTokenBuf;
>>
>> + ProcTokenBuffer = AllocatePool (ProcTokenSize * TokenCountPerChunk);
>>
>> + ASSERT (ProcTokenBuffer != NULL);
>>
>> +
>>
>> + for (Index = 0; Index < TokenCountPerChunk; Index++) {
>>
>> + SpinLock = (SPIN_LOCK *)(SpinLockBuffer + SpinLockSize * Index);
>>
>> + InitializeSpinLock (SpinLock);
>>
>> +
>>
>> + ProcToken = (PROCEDURE_TOKEN *)(ProcTokenBuffer + ProcTokenSize *
>> Index);
>>
>> + ProcToken->Signature = PROCEDURE_TOKEN_SIGNATURE;
>>
>> + ProcToken->SpinLock = SpinLock;
>>
>> + ProcToken->Used = FALSE;
>>
>> + ProcToken->RunningApCount = 0;
>>
>> +
>>
>> + InsertTailList (&gSmmCpuPrivate->TokenList, &ProcToken->Link);
>>
>> + }
>>
>> +}
>>
>>
>>
>> - InsertTailList (&gSmmCpuPrivate->OldTokenBufList, &TokenBuf->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;
>>
>>
>>
>> - gSmmCpuPrivate->CurrentTokenBuf = AllocatePool (SpinLockSize *
>> TokenCountPerChunk);
>>
>> - ASSERT (gSmmCpuPrivate->CurrentTokenBuf != NULL);
>>
>> - gSmmCpuPrivate->UsedTokenNum = 0;
>>
>> + Link = GetFirstNode (&gSmmCpuPrivate->TokenList);
>>
>> + while (!IsNull (&gSmmCpuPrivate->TokenList, Link)) {
>>
>> + ProcToken = PROCEDURE_TOKEN_FROM_LINK (Link);
>>
>> +
>>
>> + if (!ProcToken->Used) {
>>
>> + return ProcToken;
>>
>> + }
>>
>> +
>>
>> + Link = GetNextNode (&gSmmCpuPrivate->TokenList, Link);
>>
>> }
>>
>>
>>
>> - SpinLock = (SPIN_LOCK *)(gSmmCpuPrivate->CurrentTokenBuf +
>> SpinLockSize * gSmmCpuPrivate->UsedTokenNum);
>>
>> - gSmmCpuPrivate->UsedTokenNum++;
>>
>> + return NULL;
>>
>> +}
>>
>> +
>>
>> +/**
>>
>> + Get the free token.
>>
>> +
>>
>> + If no free token, allocate new tokens then return the free one.
>>
>> +
>>
>> + @retval return the first free PROCEDURE_TOKEN.
>>
>>
>>
>> - InitializeSpinLock (SpinLock);
>>
>> - AcquireSpinLock (SpinLock);
>>
>> +**/
>>
>> +PROCEDURE_TOKEN *
>>
>> +GetFreeToken (
>>
>> + IN UINT32 RunningApsCount
>>
>> + )
>>
>> +{
>>
>> + PROCEDURE_TOKEN *NewToken;
>>
>>
>>
>> - ProcToken = AllocatePool (sizeof (PROCEDURE_TOKEN));
>>
>> - ASSERT (ProcToken != NULL);
>>
>> - ProcToken->Signature = PROCEDURE_TOKEN_SIGNATURE;
>>
>> - ProcToken->SpinLock = SpinLock;
>>
>> - ProcToken->RunningApCount = RunningApCount;
>>
>> + NewToken = FindFirstFreeToken ();
>>
>> + if (NewToken == NULL) {
>>
>> + AllocateTokenBuffer ();
>>
>> + NewToken = FindFirstFreeToken ();
>>
>> + }
>>
>> + ASSERT (NewToken != NULL);
>>
>>
>>
>> - InsertTailList (&gSmmCpuPrivate->TokenList, &ProcToken->Link);
>>
>> + NewToken->Used = TRUE;
>>
>> + NewToken->RunningApCount = RunningApsCount;
>>
>> + AcquireSpinLock (NewToken->SpinLock);
>>
>>
>>
>> - return ProcToken;
>>
>> + return NewToken;
>>
>> }
>>
>>
>>
>> /**
>>
>> @@ -1231,7 +1273,7 @@ InternalSmmStartupThisAp (
>> mSmmMpSyncData->CpuData[CpuIndex].Procedure = Procedure;
>>
>> mSmmMpSyncData->CpuData[CpuIndex].Parameter = ProcArguments;
>>
>> if (Token != NULL) {
>>
>> - ProcToken= CreateToken (1);
>>
>> + ProcToken= GetFreeToken (1);
>>
>> mSmmMpSyncData->CpuData[CpuIndex].Token = ProcToken;
>>
>> *Token = (MM_COMPLETION)ProcToken->SpinLock;
>>
>> }
>>
>> @@ -1320,7 +1362,7 @@ InternalSmmStartupAllAPs (
>> }
>>
>>
>>
>> if (Token != NULL) {
>>
>> - ProcToken = CreateToken ((UINT32)mMaxNumberOfCpus);
>>
>> + ProcToken = GetFreeToken ((UINT32)mMaxNumberOfCpus);
>>
>> *Token = (MM_COMPLETION)ProcToken->SpinLock;
>>
>> } else {
>>
>> ProcToken = NULL;
>>
>> @@ -1732,28 +1774,12 @@ InitializeDataForMmMp (
>> VOID
>>
>> )
>>
>> {
>>
>> - UINTN SpinLockSize;
>>
>> - UINT32 TokenCountPerChunk;
>>
>> -
>>
>> - SpinLockSize = GetSpinLockProperties ();
>>
>> - TokenCountPerChunk = FixedPcdGet32
>> (PcdCpuSmmMpTokenCountPerChunk);
>>
>> - ASSERT (TokenCountPerChunk != 0);
>>
>> - if (TokenCountPerChunk == 0) {
>>
>> - DEBUG ((DEBUG_ERROR, "PcdCpuSmmMpTokenCountPerChunk should
>> not be Zero!\n"));
>>
>> - CpuDeadLoop ();
>>
>> - }
>>
>> - DEBUG ((DEBUG_INFO, "CpuSmm: SpinLock Size = 0x%x,
>> PcdCpuSmmMpTokenCountPerChunk = 0x%x\n", SpinLockSize,
>> TokenCountPerChunk));
>>
>> -
>>
>> - gSmmCpuPrivate->CurrentTokenBuf = AllocatePool (SpinLockSize *
>> TokenCountPerChunk);
>>
>> - ASSERT (gSmmCpuPrivate->CurrentTokenBuf != NULL);
>>
>> -
>>
>> - gSmmCpuPrivate->UsedTokenNum = 0;
>>
>> -
>>
>> gSmmCpuPrivate->ApWrapperFunc = AllocatePool (sizeof
>> (PROCEDURE_WRAPPER) * gSmmCpuPrivate-
>>> SmmCoreEntryContext.NumberOfCpus);
>>
>> ASSERT (gSmmCpuPrivate->ApWrapperFunc != NULL);
>>
>>
>>
>> InitializeListHead (&gSmmCpuPrivate->TokenList);
>>
>> - InitializeListHead (&gSmmCpuPrivate->OldTokenBufList);
>>
>> +
>>
>> + AllocateTokenBuffer ();
>>
>> }
>>
>>
>>
>> /**
>>
>> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
>> b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
>> index 5c98494e2c..33b3dd140e 100644
>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
>> @@ -214,6 +214,7 @@ typedef struct {
>>
>>
>> SPIN_LOCK *SpinLock;
>>
>> volatile UINT32 RunningApCount;
>>
>> + BOOLEAN Used;
>>
>> } PROCEDURE_TOKEN;
>>
>>
>>
>> #define PROCEDURE_TOKEN_FROM_LINK(a) CR (a, PROCEDURE_TOKEN,
>> Link, PROCEDURE_TOKEN_SIGNATURE)
>>
>> @@ -254,11 +255,6 @@ typedef struct {
>>
>>
>> PROCEDURE_WRAPPER *ApWrapperFunc;
>>
>> LIST_ENTRY TokenList;
>>
>> -
>>
>> - LIST_ENTRY OldTokenBufList;
>>
>> -
>>
>> - UINT8 *CurrentTokenBuf;
>>
>> - UINT32 UsedTokenNum; // Only record tokens used in
>> CurrentTokenBuf.
>>
>> } SMM_CPU_PRIVATE_DATA;
>>
>>
>>
>> extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate;
>>
>> --
>> 2.23.0.windows.1
>
prev parent reply other threads:[~2020-01-02 15:12 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-27 7:48 [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Pre-allocate PROCEDURE_TOKEN buffer Dong, Eric
2020-01-02 3:30 ` Ni, Ray
2020-01-02 15:12 ` Laszlo Ersek [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53138ceb-61db-6e1d-0743-1ce81525e0fb@redhat.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox