Current memory profile feature:
1. Shows which line of code calls gBS->AllocateXXX(). But most entries
are from MemoryAllocationLib.
2. Records at the start.
3. Records all modules.

Enhanced memory profile feature:
1. User can know which line of code calls AllocateXXX() API instead of
gBS->Allocate().
2. User can know which line of code calls a specific API that will call
AllocateXXX().
3. User can know total memory allocated by a specific line of code.
4. User can configure to record single module.
5. User can configure when to enable recording.
6. User can know RVA<->Symbol (Function, Source, Line).

For the enhanced memory profile feature,
1. Extend MEMORY_PROFILE_DRIVER_INFO to include PdbString.
2. Extend MEMORY_PROFILE_ALLOC_INFO to include ActionString.
3. Extend MEMORY_PROFILE_ACTION to indicate action in memory allocation
lib and user defined action.
4. Extend memory profile protocol to include GetRecordingState/
SetRecordingState/Record.
5. Define SMM memory profile protocol.
6. Extend PcdMemoryProfilePropertyMask to support disable recording at
the start.
7. Introduce new PCD PcdMemoryProfileDriverPath to control which drivers
need memory profile data.

Cc: Jiewen Yao <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <[email protected]>
---
 MdeModulePkg/Include/Guid/MemoryProfile.h | 189 ++++++++++++++++++++++++++++--
 MdeModulePkg/MdeModulePkg.dec             |  16 +++
 MdeModulePkg/MdeModulePkg.uni             |  17 ++-
 3 files changed, 212 insertions(+), 10 deletions(-)

diff --git a/MdeModulePkg/Include/Guid/MemoryProfile.h 
b/MdeModulePkg/Include/Guid/MemoryProfile.h
index 9c70b9df3924..38a64945e368 100644
--- a/MdeModulePkg/Include/Guid/MemoryProfile.h
+++ b/MdeModulePkg/Include/Guid/MemoryProfile.h
@@ -15,6 +15,8 @@
 #ifndef _MEMORY_PROFILE_H_
 #define _MEMORY_PROFILE_H_
 
+#include <Pi/PiFirmwareFile.h>
+
 //
 // For BIOS MemoryType (0 ~ EfiMaxMemoryType - 1), it is recorded in 
UsageByType[MemoryType]. (Each valid entry has one entry)
 // For OS MemoryType (0x80000000 ~ 0xFFFFFFFF), it is recorded in 
UsageByType[EfiMaxMemoryType]. (All types are combined into one entry)
@@ -42,7 +44,7 @@ typedef struct {
 } MEMORY_PROFILE_CONTEXT;
 
 #define MEMORY_PROFILE_DRIVER_INFO_SIGNATURE SIGNATURE_32 ('M','P','D','I')
-#define MEMORY_PROFILE_DRIVER_INFO_REVISION 0x0002
+#define MEMORY_PROFILE_DRIVER_INFO_REVISION 0x0003
 
 typedef struct {
   MEMORY_PROFILE_COMMON_HEADER  Header;
@@ -58,6 +60,9 @@ typedef struct {
   UINT64                        PeakUsage;
   UINT64                        CurrentUsageByType[EfiMaxMemoryType + 2];
   UINT64                        PeakUsageByType[EfiMaxMemoryType + 2];
+  UINT16                        PdbStringOffset;
+  UINT8                         Reserved2[6];
+//CHAR8                         PdbString[];
 } MEMORY_PROFILE_DRIVER_INFO;
 
 typedef enum {
@@ -67,8 +72,75 @@ typedef enum {
   MemoryProfileActionFreePool = 4,
 } MEMORY_PROFILE_ACTION;
 
+//
+// Below is the detailed MEMORY_PROFILE_ACTION definition.
+//
+//  31       15      9  8  8 7  7 6   6 5-4  3 - 0
+// +----------------------------------------------+
+// |User |  |Lib|   |Re|Copy|Zero|Align|Type|Basic|
+// +----------------------------------------------+
+//
+
+//
+// Basic Action
+//      1 : AllocatePages
+//      2 : FreePages
+//      3 : AllocatePool
+//      4 : FreePool
+//
+#define MEMORY_PROFILE_ACTION_BASIC_MASK 0xF
+
+//
+// Extension
+//
+#define MEMORY_PROFILE_ACTION_EXTENSION_MASK               0xFFF0
+#define MEMORY_PROFILE_ACTION_EXTENSION_LIB_MASK           0x8000
+#define MEMORY_PROFILE_ACTION_EXTENSION_REALLOC_MASK       0x0200
+#define MEMORY_PROFILE_ACTION_EXTENSION_COPY_MASK          0x0100
+#define MEMORY_PROFILE_ACTION_EXTENSION_ZERO_MASK          0x0080
+#define MEMORY_PROFILE_ACTION_EXTENSION_ALIGN_MASK         0x0040
+#define MEMORY_PROFILE_ACTION_EXTENSION_MEM_TYPE_MASK      0x0030
+#define MEMORY_PROFILE_ACTION_EXTENSION_MEM_TYPE_BASIC     0x0000
+#define MEMORY_PROFILE_ACTION_EXTENSION_MEM_TYPE_RUNTIME   0x0010
+#define MEMORY_PROFILE_ACTION_EXTENSION_MEM_TYPE_RESERVED  0x0020
+
+//
+// Extension (used by memory allocation lib)
+//
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES                    0x8001
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES            0x8011
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES           0x8021
+#define MEMORY_PROFILE_ACTION_LIB_FREE_PAGES                        0x8002
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES            0x8041
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES    0x8051
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES   0x8061
+#define MEMORY_PROFILE_ACTION_LIB_FREE_ALIGNED_PAGES                0x8042
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL                     0x8003
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL             0x8013
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL            0x8023
+#define MEMORY_PROFILE_ACTION_LIB_FREE_POOL                         0x8004
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL                0x8083
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL        0x8093
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL       0x80a3
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL                0x8103
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL        0x8113
+#define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL       0x8123
+#define MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL                   0x8203
+#define MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL           0x8213
+#define MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL          0x8223
+
+//
+// User defined: 0x80000000~0xFFFFFFFF
+//
+// NOTE: User defined action MUST OR the basic action,
+//       so that core can know the action is allocate or free,
+//       and the type is pages (can be freed partially)
+//       or pool (cannot be freed partially).
+//
+#define MEMORY_PROFILE_ACTION_USER_DEFINED_MASK           0x80000000
+
 #define MEMORY_PROFILE_ALLOC_INFO_SIGNATURE SIGNATURE_32 ('M','P','A','I')
-#define MEMORY_PROFILE_ALLOC_INFO_REVISION 0x0001
+#define MEMORY_PROFILE_ALLOC_INFO_REVISION 0x0002
 
 typedef struct {
   MEMORY_PROFILE_COMMON_HEADER  Header;
@@ -79,6 +151,9 @@ typedef struct {
   EFI_MEMORY_TYPE               MemoryType;
   PHYSICAL_ADDRESS              Buffer;
   UINT64                        Size;
+  UINT16                        ActionStringOffset;
+  UINT8                         Reserved2[6];
+//CHAR8                         ActionString[];
 } MEMORY_PROFILE_ALLOC_INFO;
 
 #define MEMORY_PROFILE_DESCRIPTOR_SIGNATURE SIGNATURE_32 ('M','P','D','R')
@@ -141,6 +216,7 @@ typedef struct _EDKII_MEMORY_PROFILE_PROTOCOL 
EDKII_MEMORY_PROFILE_PROTOCOL;
   @param[out]     ProfileBuffer     Profile buffer.
                       
   @return EFI_SUCCESS               Get the memory profile data successfully.
+  @return EFI_UNSUPPORTED           Memory profile is unsupported.
   @return EFI_BUFFER_TO_SMALL       The ProfileSize is too small for the 
resulting data. 
                                     ProfileSize is updated with the size 
required.
 
@@ -162,8 +238,10 @@ EFI_STATUS
   @param[in] ImageSize          Image size.
   @param[in] FileType           File type of the image.
 
-  @return EFI_SUCCESS           Register success.
-  @return EFI_OUT_OF_RESOURCE   No enough resource for this register.
+  @return EFI_SUCCESS           Register successfully.
+  @return EFI_UNSUPPORTED       Memory profile is unsupported,
+                                or memory profile for the image is not 
required.
+  @return EFI_OUT_OF_RESOURCES  No enough resource for this register.
 
 **/
 typedef
@@ -184,7 +262,9 @@ EFI_STATUS
   @param[in] ImageBase          Image base address.
   @param[in] ImageSize          Image size.
 
-  @return EFI_SUCCESS           Unregister success.
+  @return EFI_SUCCESS           Unregister successfully.
+  @return EFI_UNSUPPORTED       Memory profile is unsupported,
+                                or memory profile for the image is not 
required.
   @return EFI_NOT_FOUND         The image is not found.
 
 **/
@@ -197,10 +277,86 @@ EFI_STATUS
   IN UINT64                             ImageSize
   );
 
+#define MEMORY_PROFILE_RECORDING_ENABLE     TRUE
+#define MEMORY_PROFILE_RECORDING_DISABLE    FALSE
+
+/**
+  Get memory profile recording state.
+
+  @param[in]  This              The EDKII_MEMORY_PROFILE_PROTOCOL instance.
+  @param[out] RecordingState    Recording state.
+
+  @return EFI_SUCCESS           Memory profile recording state is returned.
+  @return EFI_UNSUPPORTED       Memory profile is unsupported.
+  @return EFI_INVALID_PARAMETER RecordingState is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_MEMORY_PROFILE_GET_RECORDING_STATE) (
+  IN EDKII_MEMORY_PROFILE_PROTOCOL      *This,
+  OUT BOOLEAN                           *RecordingState
+  );
+
+/**
+  Set memory profile recording state.
+
+  @param[in] This               The EDKII_MEMORY_PROFILE_PROTOCOL instance.
+  @param[in] RecordingState     Recording state.
+
+  @return EFI_SUCCESS           Set memory profile recording state 
successfully.
+  @return EFI_UNSUPPORTED       Memory profile is unsupported.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_MEMORY_PROFILE_SET_RECORDING_STATE) (
+  IN EDKII_MEMORY_PROFILE_PROTOCOL      *This,
+  IN BOOLEAN                            RecordingState
+  );
+
+/**
+  Record memory profile of multilevel caller.
+
+  @param[in] This               The EDKII_MEMORY_PROFILE_PROTOCOL instance.
+  @param[in] CallerAddress      Address of caller.
+  @param[in] Action             Memory profile action.
+  @param[in] MemoryType         Memory type.
+                                EfiMaxMemoryType means the MemoryType is 
unknown.
+  @param[in] Buffer             Buffer address.
+  @param[in] Size               Buffer size.
+  @param[in] ActionString       String for memory profile action.
+                                Only needed for user defined allocate action.
+
+  @return EFI_SUCCESS           Memory profile is updated.
+  @return EFI_UNSUPPORTED       Memory profile is unsupported,
+                                or memory profile for the image is not 
required,
+                                or memory profile for the memory type is not 
required.
+  @return EFI_ACCESS_DENIED     It is during memory profile data getting.
+  @return EFI_ABORTED           Memory profile recording is not enabled.
+  @return EFI_OUT_OF_RESOURCES  No enough resource to update memory profile 
for allocate action.
+  @return EFI_NOT_FOUND         No matched allocate info found for free action.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_MEMORY_PROFILE_RECORD) (
+  IN EDKII_MEMORY_PROFILE_PROTOCOL      *This,
+  IN PHYSICAL_ADDRESS                   CallerAddress,
+  IN MEMORY_PROFILE_ACTION              Action,
+  IN EFI_MEMORY_TYPE                    MemoryType,
+  IN VOID                               *Buffer,
+  IN UINTN                              Size,
+  IN CHAR8                              *ActionString OPTIONAL
+  );
+
 struct _EDKII_MEMORY_PROFILE_PROTOCOL {
-  EDKII_MEMORY_PROFILE_GET_DATA         GetData;
-  EDKII_MEMORY_PROFILE_REGISTER_IMAGE   RegisterImage;
-  EDKII_MEMORY_PROFILE_UNREGISTER_IMAGE UnregisterImage;
+  EDKII_MEMORY_PROFILE_GET_DATA             GetData;
+  EDKII_MEMORY_PROFILE_REGISTER_IMAGE       RegisterImage;
+  EDKII_MEMORY_PROFILE_UNREGISTER_IMAGE     UnregisterImage;
+  EDKII_MEMORY_PROFILE_GET_RECORDING_STATE  GetRecordingState;
+  EDKII_MEMORY_PROFILE_SET_RECORDING_STATE  SetRecordingState;
+  EDKII_MEMORY_PROFILE_RECORD               Record;
 };
 
 //
@@ -246,6 +402,8 @@ struct _EDKII_MEMORY_PROFILE_PROTOCOL {
 #define SMRAM_PROFILE_COMMAND_UNREGISTER_IMAGE           0x4
 
 #define SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET 0x5
+#define SMRAM_PROFILE_COMMAND_GET_RECORDING_STATE        0x6
+#define SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE        0x7
 
 typedef struct {
   UINT32                            Command;
@@ -281,6 +439,11 @@ typedef struct {
 
 typedef struct {
   SMRAM_PROFILE_PARAMETER_HEADER    Header;
+  BOOLEAN                           RecordingState;
+} SMRAM_PROFILE_PARAMETER_RECORDING_STATE;
+
+typedef struct {
+  SMRAM_PROFILE_PARAMETER_HEADER    Header;
   EFI_GUID                          FileName;
   PHYSICAL_ADDRESS                  ImageBuffer;
   UINT64                            NumberOfPage;
@@ -295,10 +458,18 @@ typedef struct {
 
 
 #define EDKII_MEMORY_PROFILE_GUID { \
-  0x821c9a09, 0x541a, 0x40f6, 0x9f, 0x43, 0xa, 0xd1, 0x93, 0xa1, 0x2c, 0xfe \
+  0x821c9a09, 0x541a, 0x40f6, { 0x9f, 0x43, 0xa, 0xd1, 0x93, 0xa1, 0x2c, 0xfe 
} \
 }
 
 extern EFI_GUID gEdkiiMemoryProfileGuid;
 
+typedef EDKII_MEMORY_PROFILE_PROTOCOL EDKII_SMM_MEMORY_PROFILE_PROTOCOL;
+
+#define EDKII_SMM_MEMORY_PROFILE_GUID { \
+  0xe22bbcca, 0x516a, 0x46a8, { 0x80, 0xe2, 0x67, 0x45, 0xe8, 0x36, 0x93, 0xbd 
} \
+}
+
+extern EFI_GUID gEdkiiSmmMemoryProfileGuid;
+
 #endif
 
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 27efb378bde9..4c1ac7b2a226 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -327,6 +327,7 @@ [Guids]
 
   ## Include/Guid/MemoryProfile.h
   gEdkiiMemoryProfileGuid              = { 0x821c9a09, 0x541a, 0x40f6, { 0x9f, 
0x43, 0xa, 0xd1, 0x93, 0xa1, 0x2c, 0xfe }}
+  gEdkiiSmmMemoryProfileGuid           = { 0xe22bbcca, 0x516a, 0x46a8, { 0x80, 
0xe2, 0x67, 0x45, 0xe8, 0x36, 0x93, 0xbd }}
 
   ## Include/Protocol/VarErrorFlag.h
   gEdkiiVarErrorFlagGuid               = { 0x4b37fe8, 0xf6ae, 0x480b, { 0xbd, 
0xd5, 0x37, 0xd9, 0x8c, 0x5e, 0x89, 0xaa } }
@@ -995,6 +996,7 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
   ## The mask is used to control memory profile behavior.<BR><BR>
   #  BIT0 - Enable UEFI memory profile.<BR>
   #  BIT1 - Enable SMRAM profile.<BR>
+  #  BIT7 - Disable recording at the start.<BR>
   # @Prompt Memory Profile Property.
   # @Expression  0x80000002 | 
(gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask & 0xFC) == 0
   
gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask|0x0|UINT8|0x30001041
@@ -1026,6 +1028,20 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
   # @Prompt Memory profile memory type.
   
gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileMemoryType|0x0|UINT64|0x30001042
 
+  ## This PCD is to control which drivers need memory profile data.<BR><BR>
+  # For example:<BR>
+  # One image only (Shell):<BR>
+  #     Header                    GUID<BR>
+  #     {0x04, 0x06, 0x14, 0x00,  0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 
0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1,<BR>
+  #      0x7F, 0xFF, 0x04, 0x00}<BR>
+  # Two or more images (Shell + WinNtSimpleFileSystem):<BR>
+  #     {0x04, 0x06, 0x14, 0x00,  0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 
0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1,<BR>
+  #      0x7F, 0x01, 0x04, 0x00,<BR>
+  #      0x04, 0x06, 0x14, 0x00,  0x8B, 0xE1, 0x25, 0x9C, 0xBA, 0x76, 0xDA, 
0x43, 0xA1, 0x32, 0xDB, 0xB0, 0x99, 0x7C, 0xEF, 0xEF,<BR>
+  #      0x7F, 0xFF, 0x04, 0x00}<BR>
+  # @Prompt Memory profile driver path.
+  
gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath|{0x0}|VOID*|0x00001043
+
   ## PCI Serial Device Info. It is an array of Device, Function, and Power 
Management
   #  information that describes the path that contains zero or more PCI to PCI 
briges
   #  followed by a PCI serial device.  Each array entry is 4-bytes in length.  
The
diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni
index f529dced6f0e..1a5f24efbf3e 100644
--- a/MdeModulePkg/MdeModulePkg.uni
+++ b/MdeModulePkg/MdeModulePkg.uni
@@ -266,7 +266,8 @@
 
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdMemoryProfilePropertyMask_HELP  
#language en-US "The mask is used to control memory profile behavior.<BR><BR>\n"
                                                                                
            "BIT0 - Enable UEFI memory profile.<BR>\n"
-                                                                               
            "BIT1 - Enable SMRAM profile.<BR>"
+                                                                               
            "BIT1 - Enable SMRAM profile.<BR>\n"
+                                                                               
            "BIT7 - Disable recording at the start.<BR>"
 
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdMemoryProfileMemoryType_PROMPT  
#language en-US "Memory profile memory type"
 
@@ -292,6 +293,20 @@
                                                                                
    " OS Reserved                0x80000000<BR>\n"
                                                                                
    "e.g. Reserved+ACPINvs+ACPIReclaim+RuntimeCode+RuntimeData are needed, 
0x661 should be used.<BR>\n"
 
+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdMemoryProfileDriverPath_PROMPT  
#language en-US "Memory profile driver path"
+
+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdMemoryProfileDriverPath_HELP  
#language en-US "This PCD is to control which drivers need memory profile 
data.<BR><BR>\n"
+                                                                               
    "For example:<BR>\n"
+                                                                               
    "One image only (Shell):<BR>\n"
+                                                                               
    "    Header                    GUID<BR>\n"
+                                                                               
    "    {0x04, 0x06, 0x14, 0x00,  0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 
0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1,<BR>\n"
+                                                                               
    "     0x7F, 0xFF, 0x04, 0x00}<BR>\n"
+                                                                               
    "Two or more images (Shell + WinNtSimpleFileSystem):<BR>\n"
+                                                                               
    "    {0x04, 0x06, 0x14, 0x00,  0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 
0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1,<BR>\n"
+                                                                               
    "     0x7F, 0x01, 0x04, 0x00,<BR>\n"
+                                                                               
    "     0x04, 0x06, 0x14, 0x00,  0x8B, 0xE1, 0x25, 0x9C, 0xBA, 0x76, 0xDA, 
0x43, 0xA1, 0x32, 0xDB, 0xB0, 0x99, 0x7C, 0xEF, 0xEF,<BR>\n"
+                                                                               
    "     0x7F, 0xFF, 0x04, 0x00}<BR>\n"
+
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdSerialClockRate_PROMPT  
#language en-US "Serial Port Clock Rate"
 
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdSerialClockRate_HELP  #language 
en-US "UART clock frequency is for the baud rate configuration."
-- 
2.7.0.windows.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to