diff options
author | Eric Dong <eric.dong@intel.com> | 2019-12-06 11:36:35 +0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2019-12-06 06:41:16 +0000 |
commit | 9caaa79dd7e078ebb4012dde3b3d3a5d451df609 (patch) | |
tree | 65d11532ed777c03aedf8f4bf84d44d60a7a17ae /UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | |
parent | 490a62beb7e1d084f14a93b895f9c89a49e4a51d (diff) | |
download | edk2-9caaa79dd7e078ebb4012dde3b3d3a5d451df609.tar.gz edk2-9caaa79dd7e078ebb4012dde3b3d3a5d451df609.tar.bz2 edk2-9caaa79dd7e078ebb4012dde3b3d3a5d451df609.zip |
UefiCpuPkg/PiSmmCpuDxeSmm: Avoid allocate Token every time
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.
Reviewed-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Diffstat (limited to 'UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c')
-rw-r--r-- | UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 67 |
1 files changed, 63 insertions, 4 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index 0685637c2b..757f1056f7 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -492,6 +492,24 @@ FreeTokens ( {
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);
@@ -499,7 +517,6 @@ FreeTokens ( RemoveEntryList (&ProcToken->Link);
- FreePool ((VOID *)ProcToken->ProcedureToken);
FreePool (ProcToken);
}
}
@@ -1115,13 +1132,37 @@ CreateToken ( VOID
)
{
- PROCEDURE_TOKEN *ProcToken;
+ PROCEDURE_TOKEN *ProcToken;
SPIN_LOCK *CpuToken;
UINTN SpinLockSize;
+ TOKEN_BUFFER *TokenBuf;
+ UINT32 TokenCountPerChunk;
SpinLockSize = GetSpinLockProperties ();
- CpuToken = AllocatePool (SpinLockSize);
- ASSERT (CpuToken != NULL);
+ TokenCountPerChunk = FixedPcdGet32 (PcdCpuSmmMpTokenCountPerChunk);
+
+ if (gSmmCpuPrivate->UsedTokenNum == TokenCountPerChunk) {
+ DEBUG ((DEBUG_VERBOSE, "CpuSmm: No free token buffer, allocate new buffer!\n"));
+
+ //
+ // 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;
+
+ InsertTailList (&gSmmCpuPrivate->OldTokenBufList, &TokenBuf->Link);
+
+ gSmmCpuPrivate->CurrentTokenBuf = AllocatePool (SpinLockSize * TokenCountPerChunk);
+ ASSERT (gSmmCpuPrivate->CurrentTokenBuf != NULL);
+ gSmmCpuPrivate->UsedTokenNum = 0;
+ }
+
+ CpuToken = (SPIN_LOCK *)(gSmmCpuPrivate->CurrentTokenBuf + SpinLockSize * gSmmCpuPrivate->UsedTokenNum);
+ gSmmCpuPrivate->UsedTokenNum++;
+
InitializeSpinLock (CpuToken);
AcquireSpinLock (CpuToken);
@@ -1732,10 +1773,28 @@ 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);
}
/**
|