public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Pre-allocate PROCEDURE_TOKEN buffer
@ 2019-12-27  7:48 Dong, Eric
  2020-01-02  3:30 ` Ni, Ray
  0 siblings, 1 reply; 3+ messages in thread
From: Dong, Eric @ 2019-12-27  7:48 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Laszlo Ersek

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


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Pre-allocate PROCEDURE_TOKEN buffer
  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
  0 siblings, 1 reply; 3+ messages in thread
From: Ni, Ray @ 2020-01-02  3:30 UTC (permalink / raw)
  To: Dong, Eric, devel@edk2.groups.io; +Cc: Laszlo Ersek

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----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


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] UefiCpuPkg/PiSmmCpuDxeSmm: Pre-allocate PROCEDURE_TOKEN buffer
  2020-01-02  3:30 ` Ni, Ray
@ 2020-01-02 15:12   ` Laszlo Ersek
  0 siblings, 0 replies; 3+ messages in thread
From: Laszlo Ersek @ 2020-01-02 15:12 UTC (permalink / raw)
  To: Ni, Ray, Dong, Eric, devel@edk2.groups.io

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
> 


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-01-02 15:12 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox