mirror of https://github.com/acidanthera/audk.git
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>
This commit is contained in:
parent
490a62beb7
commit
9caaa79dd7
|
@ -492,6 +492,24 @@ FreeTokens (
|
||||||
{
|
{
|
||||||
LIST_ENTRY *Link;
|
LIST_ENTRY *Link;
|
||||||
PROCEDURE_TOKEN *ProcToken;
|
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)) {
|
while (!IsListEmpty (&gSmmCpuPrivate->TokenList)) {
|
||||||
Link = GetFirstNode (&gSmmCpuPrivate->TokenList);
|
Link = GetFirstNode (&gSmmCpuPrivate->TokenList);
|
||||||
|
@ -499,7 +517,6 @@ FreeTokens (
|
||||||
|
|
||||||
RemoveEntryList (&ProcToken->Link);
|
RemoveEntryList (&ProcToken->Link);
|
||||||
|
|
||||||
FreePool ((VOID *)ProcToken->ProcedureToken);
|
|
||||||
FreePool (ProcToken);
|
FreePool (ProcToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1115,13 +1132,37 @@ CreateToken (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PROCEDURE_TOKEN *ProcToken;
|
PROCEDURE_TOKEN *ProcToken;
|
||||||
SPIN_LOCK *CpuToken;
|
SPIN_LOCK *CpuToken;
|
||||||
UINTN SpinLockSize;
|
UINTN SpinLockSize;
|
||||||
|
TOKEN_BUFFER *TokenBuf;
|
||||||
|
UINT32 TokenCountPerChunk;
|
||||||
|
|
||||||
SpinLockSize = GetSpinLockProperties ();
|
SpinLockSize = GetSpinLockProperties ();
|
||||||
CpuToken = AllocatePool (SpinLockSize);
|
TokenCountPerChunk = FixedPcdGet32 (PcdCpuSmmMpTokenCountPerChunk);
|
||||||
ASSERT (CpuToken != NULL);
|
|
||||||
|
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);
|
InitializeSpinLock (CpuToken);
|
||||||
AcquireSpinLock (CpuToken);
|
AcquireSpinLock (CpuToken);
|
||||||
|
|
||||||
|
@ -1732,10 +1773,28 @@ InitializeDataForMmMp (
|
||||||
VOID
|
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);
|
gSmmCpuPrivate->ApWrapperFunc = AllocatePool (sizeof (PROCEDURE_WRAPPER) * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus);
|
||||||
ASSERT (gSmmCpuPrivate->ApWrapperFunc != NULL);
|
ASSERT (gSmmCpuPrivate->ApWrapperFunc != NULL);
|
||||||
|
|
||||||
InitializeListHead (&gSmmCpuPrivate->TokenList);
|
InitializeListHead (&gSmmCpuPrivate->TokenList);
|
||||||
|
InitializeListHead (&gSmmCpuPrivate->OldTokenBufList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -217,6 +217,17 @@ typedef struct {
|
||||||
|
|
||||||
#define PROCEDURE_TOKEN_FROM_LINK(a) CR (a, PROCEDURE_TOKEN, Link, PROCEDURE_TOKEN_SIGNATURE)
|
#define PROCEDURE_TOKEN_FROM_LINK(a) CR (a, PROCEDURE_TOKEN, Link, PROCEDURE_TOKEN_SIGNATURE)
|
||||||
|
|
||||||
|
#define TOKEN_BUFFER_SIGNATURE SIGNATURE_32 ('T', 'K', 'B', 'S')
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINTN Signature;
|
||||||
|
LIST_ENTRY Link;
|
||||||
|
|
||||||
|
UINT8 *Buffer;
|
||||||
|
} TOKEN_BUFFER;
|
||||||
|
|
||||||
|
#define TOKEN_BUFFER_FROM_LINK(a) CR (a, TOKEN_BUFFER, Link, TOKEN_BUFFER_SIGNATURE)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Private structure for the SMM CPU module that is stored in DXE Runtime memory
|
// Private structure for the SMM CPU module that is stored in DXE Runtime memory
|
||||||
// Contains the SMM Configuration Protocols that is produced.
|
// Contains the SMM Configuration Protocols that is produced.
|
||||||
|
@ -243,6 +254,10 @@ typedef struct {
|
||||||
PROCEDURE_WRAPPER *ApWrapperFunc;
|
PROCEDURE_WRAPPER *ApWrapperFunc;
|
||||||
LIST_ENTRY TokenList;
|
LIST_ENTRY TokenList;
|
||||||
|
|
||||||
|
LIST_ENTRY OldTokenBufList;
|
||||||
|
|
||||||
|
UINT8 *CurrentTokenBuf;
|
||||||
|
UINT32 UsedTokenNum; // Only record tokens used in CurrentTokenBuf.
|
||||||
} SMM_CPU_PRIVATE_DATA;
|
} SMM_CPU_PRIVATE_DATA;
|
||||||
|
|
||||||
extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate;
|
extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate;
|
||||||
|
|
|
@ -140,6 +140,9 @@
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask ## CONSUMES
|
gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask ## CONSUMES
|
||||||
|
|
||||||
|
[FixedPcd]
|
||||||
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmMpTokenCountPerChunk ## CONSUMES
|
||||||
|
|
||||||
[Pcd.X64]
|
[Pcd.X64]
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess ## CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess ## CONSUMES
|
||||||
|
|
||||||
|
|
|
@ -148,6 +148,10 @@
|
||||||
# @Prompt Specify size of good stack of exception which need switching stack.
|
# @Prompt Specify size of good stack of exception which need switching stack.
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize|2048|UINT32|0x30002001
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize|2048|UINT32|0x30002001
|
||||||
|
|
||||||
|
## Count of pre allocated SMM MP tokens per chunk.
|
||||||
|
# @Prompt Specify the count of pre allocated SMM MP tokens per chunk.
|
||||||
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmMpTokenCountPerChunk|64|UINT32|0x30002002
|
||||||
|
|
||||||
[PcdsFixedAtBuild, PcdsPatchableInModule]
|
[PcdsFixedAtBuild, PcdsPatchableInModule]
|
||||||
## This value is the CPU Local APIC base address, which aligns the address on a 4-KByte boundary.
|
## This value is the CPU Local APIC base address, which aligns the address on a 4-KByte boundary.
|
||||||
# @Prompt Configure base address of CPU Local APIC
|
# @Prompt Configure base address of CPU Local APIC
|
||||||
|
|
|
@ -272,3 +272,6 @@
|
||||||
"24000000 - 6th and 7th generation Intel Core processors and Intel Xeon W Processor Family(24MHz).<BR>\n"
|
"24000000 - 6th and 7th generation Intel Core processors and Intel Xeon W Processor Family(24MHz).<BR>\n"
|
||||||
"19200000 - Intel Atom processors based on Goldmont Microarchitecture with CPUID signature 06_5CH(19.2MHz).<BR>\n"
|
"19200000 - Intel Atom processors based on Goldmont Microarchitecture with CPUID signature 06_5CH(19.2MHz).<BR>\n"
|
||||||
|
|
||||||
|
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmMpTokenCountPerChunk_PROMPT #language en-US "Specify the count of pre allocated SMM MP tokens per chunk.\n"
|
||||||
|
|
||||||
|
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmMpTokenCountPerChunk_HELP #language en-US "This value used to specify the count of pre allocated SMM MP tokens per chunk.\n"
|
||||||
|
|
Loading…
Reference in New Issue