mirror of https://github.com/acidanthera/audk.git
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>
This commit is contained in:
parent
0da3df78ff
commit
ad6c8540cc
|
@ -778,6 +778,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.
|
||||
//
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -60,6 +60,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
|
||||
#include "CpuService.h"
|
||||
#include "SmmProfile.h"
|
||||
#include "SmmMpPerf.h"
|
||||
|
||||
//
|
||||
// CET definition
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
SmmCpuMemoryManagement.c
|
||||
SmmMp.h
|
||||
SmmMp.c
|
||||
SmmMpPerf.h
|
||||
SmmMpPerf.c
|
||||
|
||||
[Sources.Ia32]
|
||||
Ia32/Semaphore.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 ();
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue