diff options
author | Ray Ni <ray.ni@intel.com> | 2023-05-26 21:34:36 +0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2023-06-21 04:37:17 +0000 |
commit | ad6c8540cc9ce06235891cb6c4c713a5c8b272fc (patch) | |
tree | e1ebd4e56d3804830ea19878bcfad50b2d87e1f2 /UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c | |
parent | 0da3df78ff469462c6c09d979fd6e2eeac0665bb (diff) | |
download | edk2-ad6c8540cc9ce06235891cb6c4c713a5c8b272fc.tar.gz edk2-ad6c8540cc9ce06235891cb6c4c713a5c8b272fc.tar.bz2 edk2-ad6c8540cc9ce06235891cb6c4c713a5c8b272fc.zip |
UefiCpuPkg/CpuSmm: Add perf-logging for MP procedures
MP procedures are those procedures that run in every CPU thread.
The EDKII perf infra is not MP safe so it doesn't support to be called
from those MP procedures.
The patch adds SMM MP perf-logging support in SmmMpPerf.c.
The following procedures are perf-logged:
* SmmInitHandler
* SmmCpuFeaturesRendezvousEntry
* PlatformValidSmi
* SmmCpuFeaturesRendezvousExit
Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Diffstat (limited to 'UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c')
-rw-r--r-- | UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c | 90 |
1 files changed, 90 insertions, 0 deletions
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 ();
+}
|