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>
91 lines
2.4 KiB
C
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 ();
|
|
}
|