]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
UefiCpuPkg/PiSmmCpuDxeSmm: Avoid allocate Token every time
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / MpService.c
index 0685637c2b51bf3e883e6adfa9aa6291058bd374..757f1056f78dd62fa3fb3b904ed7f212171f58a1 100644 (file)
@@ -492,6 +492,24 @@ FreeTokens (
 {\r
   LIST_ENTRY            *Link;\r
   PROCEDURE_TOKEN       *ProcToken;\r
+  TOKEN_BUFFER          *TokenBuf;\r
+\r
+  //\r
+  // Only free the token buffer recorded in the OldTOkenBufList\r
+  // upon exiting SMI. Current token buffer stays allocated so\r
+  // next SMI doesn't need to re-allocate.\r
+  //\r
+  gSmmCpuPrivate->UsedTokenNum = 0;\r
+\r
+  Link = GetFirstNode (&gSmmCpuPrivate->OldTokenBufList);\r
+  while (!IsNull (&gSmmCpuPrivate->OldTokenBufList, Link)) {\r
+    TokenBuf = TOKEN_BUFFER_FROM_LINK (Link);\r
+\r
+    Link = RemoveEntryList (&TokenBuf->Link);\r
+\r
+    FreePool (TokenBuf->Buffer);\r
+    FreePool (TokenBuf);\r
+  }\r
 \r
   while (!IsListEmpty (&gSmmCpuPrivate->TokenList)) {\r
     Link = GetFirstNode (&gSmmCpuPrivate->TokenList);\r
@@ -499,7 +517,6 @@ FreeTokens (
 \r
     RemoveEntryList (&ProcToken->Link);\r
 \r
-    FreePool ((VOID *)ProcToken->ProcedureToken);\r
     FreePool (ProcToken);\r
   }\r
 }\r
@@ -1115,13 +1132,37 @@ CreateToken (
   VOID\r
   )\r
 {\r
-  PROCEDURE_TOKEN    *ProcToken;\r
+  PROCEDURE_TOKEN     *ProcToken;\r
   SPIN_LOCK           *CpuToken;\r
   UINTN               SpinLockSize;\r
+  TOKEN_BUFFER        *TokenBuf;\r
+  UINT32              TokenCountPerChunk;\r
 \r
   SpinLockSize = GetSpinLockProperties ();\r
-  CpuToken = AllocatePool (SpinLockSize);\r
-  ASSERT (CpuToken != NULL);\r
+  TokenCountPerChunk = FixedPcdGet32 (PcdCpuSmmMpTokenCountPerChunk);\r
+\r
+  if (gSmmCpuPrivate->UsedTokenNum == TokenCountPerChunk) {\r
+    DEBUG ((DEBUG_VERBOSE, "CpuSmm: No free token buffer, allocate new buffer!\n"));\r
+\r
+    //\r
+    // Record current token buffer for later free action usage.\r
+    // Current used token buffer not in this list.\r
+    //\r
+    TokenBuf = AllocatePool (sizeof (TOKEN_BUFFER));\r
+    ASSERT (TokenBuf != NULL);\r
+    TokenBuf->Signature = TOKEN_BUFFER_SIGNATURE;\r
+    TokenBuf->Buffer  = gSmmCpuPrivate->CurrentTokenBuf;\r
+\r
+    InsertTailList (&gSmmCpuPrivate->OldTokenBufList, &TokenBuf->Link);\r
+\r
+    gSmmCpuPrivate->CurrentTokenBuf = AllocatePool (SpinLockSize * TokenCountPerChunk);\r
+    ASSERT (gSmmCpuPrivate->CurrentTokenBuf != NULL);\r
+    gSmmCpuPrivate->UsedTokenNum = 0;\r
+  }\r
+\r
+  CpuToken = (SPIN_LOCK *)(gSmmCpuPrivate->CurrentTokenBuf + SpinLockSize * gSmmCpuPrivate->UsedTokenNum);\r
+  gSmmCpuPrivate->UsedTokenNum++;\r
+\r
   InitializeSpinLock (CpuToken);\r
   AcquireSpinLock (CpuToken);\r
 \r
@@ -1732,10 +1773,28 @@ InitializeDataForMmMp (
   VOID\r
   )\r
 {\r
+  UINTN              SpinLockSize;\r
+  UINT32             TokenCountPerChunk;\r
+\r
+  SpinLockSize = GetSpinLockProperties ();\r
+  TokenCountPerChunk = FixedPcdGet32 (PcdCpuSmmMpTokenCountPerChunk);\r
+  ASSERT (TokenCountPerChunk != 0);\r
+  if (TokenCountPerChunk == 0) {\r
+    DEBUG ((DEBUG_ERROR, "PcdCpuSmmMpTokenCountPerChunk should not be Zero!\n"));\r
+    CpuDeadLoop ();\r
+  }\r
+  DEBUG ((DEBUG_INFO, "CpuSmm: SpinLock Size = 0x%x, PcdCpuSmmMpTokenCountPerChunk = 0x%x\n", SpinLockSize, TokenCountPerChunk));\r
+\r
+  gSmmCpuPrivate->CurrentTokenBuf = AllocatePool (SpinLockSize * TokenCountPerChunk);\r
+  ASSERT (gSmmCpuPrivate->CurrentTokenBuf != NULL);\r
+\r
+  gSmmCpuPrivate->UsedTokenNum = 0;\r
+\r
   gSmmCpuPrivate->ApWrapperFunc = AllocatePool (sizeof (PROCEDURE_WRAPPER) * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus);\r
   ASSERT (gSmmCpuPrivate->ApWrapperFunc != NULL);\r
 \r
   InitializeListHead (&gSmmCpuPrivate->TokenList);\r
+  InitializeListHead (&gSmmCpuPrivate->OldTokenBufList);\r
 }\r
 \r
 /**\r