Files
system76-edk2/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c
Ray Ni ad6c8540cc 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>
2023-06-21 04:37:17 +00:00

91 lines
2.4 KiB
C

/** @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 ();
}