summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg
diff options
context:
space:
mode:
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c34
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c11
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h1
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf2
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c90
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.h81
6 files changed, 219 insertions, 0 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
index fa666bd118..bcd90f0671 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
@@ -779,6 +779,15 @@ BSPHandler (
WaitForAllAPs (ApCount);
//
+ // At this point, all APs should have exited from APHandler().
+ // Migrate the SMM MP performance logging to standard SMM performance logging.
+ // Any SMM MP performance logging after this point will be migrated in next SMI.
+ //
+ PERF_CODE (
+ MigrateMpPerf (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus);
+ );
+
+ //
// Reset the tokens buffer.
//
ResetTokens ();
@@ -1769,12 +1778,24 @@ SmiRendezvous (
//
// Perform CPU specific entry hooks
//
+ PERF_CODE (
+ MpPerfBegin (CpuIndex, SMM_MP_PERF_PROCEDURE_ID (SmmRendezvousEntry));
+ );
SmmCpuFeaturesRendezvousEntry (CpuIndex);
+ PERF_CODE (
+ MpPerfEnd (CpuIndex, SMM_MP_PERF_PROCEDURE_ID (SmmRendezvousEntry));
+ );
//
// Determine if this is a valid SMI
//
+ PERF_CODE (
+ MpPerfBegin (CpuIndex, SMM_MP_PERF_PROCEDURE_ID (PlatformValidSmi));
+ );
ValidSmi = PlatformValidSmi ();
+ PERF_CODE (
+ MpPerfEnd (CpuIndex, SMM_MP_PERF_PROCEDURE_ID (PlatformValidSmi));
+ );
//
// Determine if BSP has been already in progress. Note this must be checked after
@@ -1904,7 +1925,20 @@ SmiRendezvous (
}
Exit:
+ //
+ // Note: SmmRendezvousExit perf-logging entry is the only one that will be
+ // migrated to standard perf-logging database in next SMI by BSPHandler().
+ // Hence, the number of SmmRendezvousEntry entries will be larger than
+ // the number of SmmRendezvousExit entries. Delta equals to the number
+ // of CPU threads.
+ //
+ PERF_CODE (
+ MpPerfBegin (CpuIndex, SMM_MP_PERF_PROCEDURE_ID (SmmRendezvousExit));
+ );
SmmCpuFeaturesRendezvousExit (CpuIndex);
+ PERF_CODE (
+ MpPerfEnd (CpuIndex, SMM_MP_PERF_PROCEDURE_ID (SmmRendezvousExit));
+ );
//
// Restore Cr2
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
index 32ca417f73..7a3ed3022d 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -362,6 +362,9 @@ SmmInitHandler (
for (Index = 0; Index < mNumberOfCpus; Index++) {
if (ApicId == (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId) {
+ PERF_CODE (
+ MpPerfBegin (Index, SMM_MP_PERF_PROCEDURE_ID (SmmInitHandler));
+ );
//
// Initialize SMM specific features on the currently executing CPU
//
@@ -392,6 +395,10 @@ SmmInitHandler (
SemaphoreHook (Index, &mRebased[Index]);
}
+ PERF_CODE (
+ MpPerfEnd (Index, SMM_MP_PERF_PROCEDURE_ID (SmmInitHandler));
+ );
+
return;
}
}
@@ -699,6 +706,10 @@ PiCpuSmmEntry (
gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus = mMaxNumberOfCpus;
+ PERF_CODE (
+ InitializeMpPerf (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus);
+ );
+
//
// The CPU save state and code for the SMI entry point are tiled within an SMRAM
// allocated buffer. The minimum size of this buffer for a uniprocessor system
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
index b03f2ef882..1876a27cae 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
@@ -60,6 +60,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "CpuService.h"
#include "SmmProfile.h"
+#include "SmmMpPerf.h"
//
// CET definition
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
index af66a1941c..4864532c35 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
@@ -42,6 +42,8 @@
SmmCpuMemoryManagement.c
SmmMp.h
SmmMp.c
+ SmmMpPerf.h
+ SmmMpPerf.c
[Sources.Ia32]
Ia32/Semaphore.c
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c
new file mode 100644
index 0000000000..f6323f9230
--- /dev/null
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c
@@ -0,0 +1,90 @@
+/** @file
+SMM MP perf-logging implementation
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiSmmCpuDxeSmm.h"
+
+#define SMM_MP_PERF_PROCEDURE_NAME(procedure) # procedure
+GLOBAL_REMOVE_IF_UNREFERENCED
+CHAR8 *gSmmMpPerfProcedureName[] = {
+ SMM_MP_PERF_PROCEDURE_LIST (SMM_MP_PERF_PROCEDURE_NAME)
+};
+//
+// Each element holds the performance data for one processor.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED
+SMM_PERF_AP_PROCEDURE_PERFORMANCE *mSmmMpProcedurePerformance = NULL;
+
+/**
+ Initialize the perf-logging feature for APs.
+
+ @param NumberofCpus Number of processors in the platform.
+**/
+VOID
+InitializeMpPerf (
+ UINTN NumberofCpus
+ )
+{
+ mSmmMpProcedurePerformance = AllocateZeroPool (NumberofCpus * sizeof (*mSmmMpProcedurePerformance));
+ ASSERT (mSmmMpProcedurePerformance != NULL);
+}
+
+/**
+ Migrate MP performance data to standardized performance database.
+
+ @param NumberofCpus Number of processors in the platform.
+**/
+VOID
+MigrateMpPerf (
+ UINTN NumberofCpus
+ )
+{
+ UINTN CpuIndex;
+ UINTN MpProcecureId;
+
+ for (CpuIndex = 0; CpuIndex < NumberofCpus; CpuIndex++) {
+ for (MpProcecureId = 0; MpProcecureId < SMM_MP_PERF_PROCEDURE_ID (SmmMpProcedureMax); MpProcecureId++) {
+ if (mSmmMpProcedurePerformance[CpuIndex].Begin[MpProcecureId] != 0) {
+ PERF_START (NULL, gSmmMpPerfProcedureName[MpProcecureId], NULL, mSmmMpProcedurePerformance[CpuIndex].Begin[MpProcecureId]);
+ PERF_END (NULL, gSmmMpPerfProcedureName[MpProcecureId], NULL, mSmmMpProcedurePerformance[CpuIndex].End[MpProcecureId]);
+ }
+ }
+ }
+
+ ZeroMem (mSmmMpProcedurePerformance, NumberofCpus * sizeof (*mSmmMpProcedurePerformance));
+}
+
+/**
+ Save the performance counter value before running the MP procedure.
+
+ @param CpuIndex The index of the CPU.
+ @param MpProcedureId The ID of the MP procedure.
+**/
+VOID
+MpPerfBegin (
+ IN UINTN CpuIndex,
+ IN UINTN MpProcedureId
+ )
+{
+ mSmmMpProcedurePerformance[CpuIndex].Begin[MpProcedureId] = GetPerformanceCounter ();
+}
+
+/**
+ Save the performance counter value after running the MP procedure.
+
+ @param CpuIndex The index of the CPU.
+ @param MpProcedureId The ID of the MP procedure.
+**/
+VOID
+MpPerfEnd (
+ IN UINTN CpuIndex,
+ IN UINTN MpProcedureId
+ )
+{
+ mSmmMpProcedurePerformance[CpuIndex].End[MpProcedureId] = GetPerformanceCounter ();
+}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.h
new file mode 100644
index 0000000000..d9f0fb9bf6
--- /dev/null
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.h
@@ -0,0 +1,81 @@
+/** @file
+SMM MP perf-logging implementation
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MP_PERF_H_
+#define MP_PERF_H_
+
+//
+// The list of all MP procedures that need to be perf-logged.
+//
+#define SMM_MP_PERF_PROCEDURE_LIST(_) \
+ _(SmmInitHandler), \
+ _(SmmRendezvousEntry), \
+ _(PlatformValidSmi), \
+ _(SmmRendezvousExit), \
+ _(SmmMpProcedureMax) // Add new entries above this line
+
+//
+// To perf-log MP procedures, call MpPerfBegin()/MpPerfEnd() with CpuIndex
+// and SMM_MP_PERF_PROCEDURE_ID with entry name defined in the SMM_MP_PERF_PROCEDURE_LIST.
+//
+#define SMM_MP_PERF_PROCEDURE_ID(procedure) SmmMpProcedureId ## procedure
+enum {
+ SMM_MP_PERF_PROCEDURE_LIST (SMM_MP_PERF_PROCEDURE_ID)
+};
+
+typedef struct {
+ UINT64 Begin[SMM_MP_PERF_PROCEDURE_ID (SmmMpProcedureMax)];
+ UINT64 End[SMM_MP_PERF_PROCEDURE_ID (SmmMpProcedureMax)];
+} SMM_PERF_AP_PROCEDURE_PERFORMANCE;
+
+/**
+ Initialize the perf-logging feature for APs.
+
+ @param NumberofCpus Number of processors in the platform.
+**/
+VOID
+InitializeMpPerf (
+ UINTN NumberofCpus
+ );
+
+/**
+ Migrate MP performance data to standardized performance database.
+
+ @param NumberofCpus Number of processors in the platform.
+**/
+VOID
+MigrateMpPerf (
+ UINTN NumberofCpus
+ );
+
+/**
+ Save the performance counter value before running the MP procedure.
+
+ @param CpuIndex The index of the CPU.
+ @param MpProcedureId The ID of the MP procedure.
+**/
+VOID
+MpPerfBegin (
+ IN UINTN CpuIndex,
+ IN UINTN MpProcedureId
+ );
+
+/**
+ Save the performance counter value after running the MP procedure.
+
+ @param CpuIndex The index of the CPU.
+ @param MpProcedureId The ID of the MP procedure.
+**/
+VOID
+MpPerfEnd (
+ IN UINTN CpuIndex,
+ IN UINTN MpProcedureId
+ );
+
+#endif