Hi Rafael,

I think your application is exposing some of the rough edges of the EDK2 
memory allocation routines. 

Your application is calling allocatepool for boot servies data. It is 
first doing this to get a handle buffer of GOP devices, then it is doing 
this to create a Blt buffer. 

Your application does free this memory, but once you understand how the 
internals of the edk2 memory allocation work, the behavior is as expected. 

e
When you call allocate pool, if the amount of memory that you are trying 
to allocate is greater than a page then the edk2 will round the amount of 
memory that you are requesting up to the next page and just allocate pages 
of memory to you.

If you call allocate pool, and the amount of memory you are trying to 
allocate is less than a page of memory, the edk2 will look at the current 
sets of memory that are of the type you are trying to allocate 
(EfiBootServicesData in your case).  If it can find an available amount of 
memory in its previously allocated pages, it will return that memory to 
you.  If it cannot find that amount of memory, it will convert available 
pages of memory into the type of memory and give that to you.

If your example code's case, you allocate for a handle buffer, then you 
allocate for a gop blt buffer, then you call blt (which may perform memory 
allocations too).  In all of this, you may have exhausted the amount of 
BootServicesData pages that were currently available and caused the system 
to convert available memory into Boot Services Data memory.

I hope this helps explain the behavior that you are seeing. 




From:   Andrew Fish <[email protected]>
To:     Rafael Machado <[email protected]>
Cc:     "Carsey, Jaben" <[email protected]>, 
"[email protected]" <[email protected]>
Date:   06/01/2016 11:16 AM
Subject:        Re: [edk2] Memory Consumption after BLT (GOP)
Sent by:        "edk2-devel" <[email protected]>




> On Jun 1, 2016, at 11:10 AM, Rafael Machado 
<[email protected]> wrote:
> 
> The draw application is this one:
> 

Yikes that is hard for me to read without indentation....

Why don't you try putting some of the GraphicProtocol calls in a loop to 
see if that leaks more memory? 

Thanks,

Andrew Fish

> #include <Uefi.h>
> #include <Library/UefiBootServicesTableLib.h>
> #include <Library/MemoryAllocationLib.h>
> #include <Library/UefiLib.h>
> #include <Library/PrintLib.h>
> #include <Library/DebugLib.h>
> #include <Protocol/GraphicsOutput.h>
> #include <Protocol/EdidActive.h>
> 
> #define BoxWidth 100
> #define BoxHeight 100
> 
> EFI_STATUS PrintImage(EFI_HANDLE ImageHandle, UINTN ImagePositionX, 
UINTN
> ImagePositionY){
> 
> UINTN Size;
> EFI_STATUS Status;
> UINTN HandleIndex = 0;
> EFI_HANDLE *HandleArray = NULL;
> EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicProtocol = NULL;
> EFI_GUID gGraphicalProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
> EFI_GUID gEdidActivated = EFI_EDID_ACTIVE_PROTOCOL_GUID;
> EFI_EDID_ACTIVE_PROTOCOL *EdidActivated = NULL;
> EFI_GRAPHICS_OUTPUT_BLT_PIXEL* inMemoryImage = NULL;
> 
> Status = gBS->LocateHandleBuffer(ByProtocol,
> &gEfiGraphicsOutputProtocolGuid,
> NULL,
> &Size,
> &HandleArray);
> 
> if(!EFI_ERROR(Status))
> {
> for(HandleIndex=0; HandleIndex<Size; HandleIndex++)
> {
> 
> Status = gBS->OpenProtocol(HandleArray[HandleIndex],
> &gGraphicalProtocol,
> (VOID**) &GraphicProtocol,
> ImageHandle,
> NULL,
> EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
> 
> if(EFI_ERROR(Status)){
> 
> gBS->CloseProtocol(HandleArray[HandleIndex],
> &gGraphicalProtocol,
> ImageHandle,
> NULL);
> 
> GraphicProtocol = NULL;
> 
> continue;
> } else {
> 
> // Verifies if current handle corresponds to current video
> Status = gBS->OpenProtocol(HandleArray[HandleIndex],
> &gEdidActivated,
> (VOID**) &EdidActivated,
> ImageHandle,
> NULL,
> EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
> 
> if(EFI_ERROR(Status)){
> 
> gBS->CloseProtocol(HandleArray[HandleIndex],
> &gGraphicalProtocol,
> ImageHandle,
> NULL);
> 
> GraphicProtocol = NULL;
> 
> gBS->CloseProtocol(HandleArray[HandleIndex],
> &gEdidActivated,
> ImageHandle,
> NULL);
> 
> EdidActivated = NULL;
> 
> continue;
> } else {
> break;
> }
> }
> }
> 
> if(!EFI_ERROR(Status))
> {
> Status = gBS->AllocatePool(EfiBootServicesData,
> sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) *
> BoxWidth * BoxHeight,
> &inMemoryImage);
> 
> if(!EFI_ERROR(Status))
> {
> 
> gBS->SetMem(inMemoryImage,
> sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) *
> BoxWidth * BoxHeight,
> 0xFF);
> 
> Status = GraphicProtocol->Blt(GraphicProtocol,
> inMemoryImage,
> EfiBltBufferToVideo,
> 0,
> 0,
> ImagePositionX,
> ImagePositionY,
> BoxWidth,
> BoxHeight,
> 0);
> 
> if(EFI_ERROR(Status)){
> Print(L"Fail to print Image");
> goto CLEAR;
> }
> } else {
> Print(L"Fail to allocate buffer");
> goto CLEAR;
> }
> 
> }else{
> Print(L"Fail to locate GraphicIoProtocol devices");
> goto CLEAR;
> }
> }
> 
> CLEAR:
> 
> if(inMemoryImage != NULL) {
> FreePool(inMemoryImage);
> inMemoryImage = NULL;
> }
> 
> if(GraphicProtocol != NULL) {
> 
> Status = gBS->CloseProtocol(HandleArray[HandleIndex],
> &gGraphicalProtocol,
> ImageHandle,
> NULL);
> 
> GraphicProtocol = NULL;
> }
> 
> if(EdidActivated != NULL) {
> 
> Status = gBS->CloseProtocol(HandleArray[HandleIndex],
> &gEdidActivated,
> ImageHandle,
> NULL);
> 
> EdidActivated = NULL;
> }
> 
> if(HandleArray != NULL) {
> FreePool(HandleArray);
> HandleArray = NULL;
> }
> 
> return Status;
> }
> 
> 
> EFI_STATUS testeMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE 
*SystemTable)
> {
> return PrintImage(ImageHandle, 50, 50);
> }
> 
> 
> Unfortunately I don't have this systems GOP driver code.
> 
> Thanks and Regards.
> Rafael R. Machado
> 
> Em qua, 1 de jun de 2016 às 15:02, Carsey, Jaben 
<[email protected]>
> escreveu:
> 
>> It’s possible that you found a leak in the driver.  Have you double
>> checked your drawing app to be sure it’s not leaking anything?  Do you 
have
>> source for the driver?
>> 
>> -Jaben
>> 
>> 
>> From: Rafael Machado [mailto:[email protected]]
>> Sent: Wednesday, June 01, 2016 11:00 AM
>> To: Carsey, Jaben <[email protected]>
>> Cc: [email protected]
>> Subject: Re: [edk2] Memory Consumption after BLT (GOP)
>> Importance: High
>> 
>> I did that :)
>> 
>> To get the available memory I did the following function:
>> 
>> EFI_STATUS CalculateAvaiableMemoryForDebug (VOID)
>> {
>> 
>>  EFI_STATUS Status = EFI_SUCCESS;
>>  EFI_MEMORY_DESCRIPTOR *MemMap = NULL;
>>  EFI_MEMORY_DESCRIPTOR *Desc;
>>  UINTN DescriptorSize = 0;
>>  UINT32 DescriptorVersion = 0; UINTN MapKey;
>>  UINTN        MemMapSize = sizeof(EFI_MEMORY_DESCRIPTOR);
>>  UINTN Index = 0;
>>  UINTN NoDesc = 0;
>> 
>> 
>>  UINTN TotalOfPages     = 0;
>>  UINTN TotalOfFreePages = 0;
>>  UINTN TotalOfBlocks    = 0;
>>  UINTN CurrentBlock     = 0;
>> 
>> 
>> 
>>  if (MemMap != NULL) {
>>      FreePool(MemMap);
>>  }
>> 
>>  Status = gBS->AllocatePool(EfiBootServicesData,
>>                             MemMapSize,
>>                             (VOID**)&MemMap);
>> 
>>  if (Status == EFI_SUCCESS) {
>>    Status = gBS->GetMemoryMap(&MemMapSize,
>>                               MemMap,
>>                               &MapKey,
>>                               &DescriptorSize,
>>                               &DescriptorVersion);
>>  } else {
>>    Status = EFI_DEVICE_ERROR;
>>  }
>> 
>>  if (Status == EFI_SUCCESS) {
>> 
>>    CurrentBlock = 1;
>>    Desc = MemMap;
>>    NoDesc = MemMapSize / DescriptorSize;
>> 
>>    for(Index = 0; Index < NoDesc; Index++) {
>> 
>>      if (Desc->Type == EfiConventionalMemory) {
>>        TotalOfFreePages += (UINTN) Desc->NumberOfPages;
>>        TotalOfBlocks++;
>>      }
>> 
>>      TotalOfPages += (UINTN) Desc->NumberOfPages;
>> 
>>      Desc = NextMemoryDescriptor (Desc, DescriptorSize);
>>    }
>> 
>>  } else {
>>    Status = EFI_DEVICE_ERROR;
>>  }
>> 
>>  if (MemMap != NULL) {
>>      FreePool(MemMap);
>>  }
>> 
>>  DEBUG_LOG(DbgFileModeMemoryAvailable,
>>             DEBUG_LEVEL_DUMP,
>>             L"-----Available Pages: %ld --------\n",
>>             TotalOfFreePages);
>> 
>> 
>>  return Status;
>> }
>> 
>> The available memory also decreases in this case.
>> I didn't find any leak at this function too.
>> 
>> I'm considering some problem with other driver that is causing this
>> memory decrease during the execution time.
>> 
>> Thanks
>> Rafael R. Machado
>> 
>> Em qua, 1 de jun de 2016 às 14:53, Carsey, Jaben 
<[email protected]
>> <mailto:[email protected]>> escreveu:
>> Well... sadly the best way to debug would be to get the memory map
>> yourself, run your graphical operation, and then compare all inside the
>> same program (assuming that you allocate no memory within your memory 
map
>> acquisitions).
>> 
>> -Jaben
>> 
>>> -----Original Message-----
>>> From: edk2-devel [mailto:[email protected]<mailto:
>> [email protected]>] On Behalf Of
>>> Rafael Machado
>>> Sent: Wednesday, June 01, 2016 10:33 AM
>>> To: Carsey, Jaben <[email protected]<
mailto:[email protected]
>>>> 
>>> Cc: [email protected]<mailto:[email protected]>
>>> Subject: Re: [edk2] Memory Consumption after BLT (GOP)
>>> Importance: High
>>> 
>>> The system has one page decreased after some executions.
>>> I used the following script to check this:
>>> 
>>> FS1:
>>> echo -off
>>> memmap >> memmapShellBefore.txt
>>> for %a run (1 10)
>>> TestesImagemBMP.efi
>>> memmap >> memmapShellAfter_%a.txt
>>> endfor
>>> 
>>> The decrease happened at execution number 4 and 9
>>> From execution 1 to 2, and 2 to 3  no decrease was detected. The same
>> with
>>> execution 4 to 5, 5 to 6 6 to 7 and 7 to 8
>>> 
>>> I thought that since I'm using the script no command log was saved by 
the
>>> shell application.
>>> At the begin I added a echo -off to avoid scroll.
>>> 
>>> 
>>> Thanks and Regards
>>> Rafael R. Machado
>>> 
>>> Em qua, 1 de jun de 2016 às 14:13, Carsey, Jaben 
<[email protected]
>> <mailto:[email protected]>>
>>> escreveu:
>>> 
>>>> Does the pattern continue or level off after time?
>>>> 
>>>> I ask as the shell will make some allocations to save things like
>> command
>>>> history and output history for up/down page up/page down support...
>>>> 
>>>> -Jaben
>>>> 
>>>>> On Jun 1, 2016, at 10:10 AM, Rafael Machado <
>>>> [email protected]<mailto:
>> [email protected]>> wrote:
>>>>> 
>>>>> Hi Everyone.
>>>>> 
>>>>> I'm doing some tests related to the GOP and graphical applications.
>>>>> What I've seeing is that after calling the GOP->BLT several times 
the
>>>>> available memory from the system decrease.
>>>>> 
>>>>> For example. When the system just boot I have the following at the
>> uefi
>>>>> shell memmap command:
>>>>> 
>>>>> reserved  :     124 Pages (507,904)
>>>>> LoaderCode:     186 Pages (761,856)
>>>>> LoaderData:      24 Pages (98,304)
>>>>> BS_code   :   1,719 Pages (7,041,024)
>>>>> BS_data   :  10,774 Pages (44,130,304)
>>>>> RT_code   :     256 Pages (1,048,576)
>>>>> RT_data   :     660 Pages (2,703,360)
>>>>> *available : 407,184 Pages (1,667,825,664)*
>>>>> ACPI_recl :      96 Pages (393,216)
>>>>> ACPI_NVS  :     129 Pages (528,384)
>>>>> MemMapIO  :       1 Pages (4,096)
>>>>> Total Memory: 1,644 MB (1,724,530,688) Bytes
>>>>> 
>>>>> After executing a sample application that just draw a white box 10
>>>> times, I
>>>>> have the following:
>>>>> 
>>>>> reserved  :     124 Pages (507,904)
>>>>> LoaderCode:     186 Pages (761,856)
>>>>> LoaderData:      24 Pages (98,304)
>>>>> BS_code   :   1,719 Pages (7,041,024)
>>>>> BS_data   :  10,776 Pages (44,138,496)
>>>>> RT_code   :     256 Pages (1,048,576)
>>>>> RT_data   :     660 Pages (2,703,360)
>>>>> * available : 407,182 Pages (1,667,817,472)*
>>>>> ACPI_recl :      96 Pages (393,216)
>>>>> ACPI_NVS  :     129 Pages (528,384)
>>>>> MemMapIO  :       1 Pages (4,096)
>>>>> Total Memory: 1,644 MB (1,724,530,688) Bytes
>>>>> 
>>>>> 
>>>>> So the situation is that on a Graphical UEFI application, there is a
>>>>> possibility of getting too much memory.
>>>>> As much as I execute the application the available memory keeps
>>>> decreasing.
>>>>> 
>>>>> Could someone please help me to find some problem on the sample
>>>> application
>>>>> code ?
>>>>> 
>>>>> "
>>>>> #include <Uefi.h>
>>>>> #include <Library/UefiBootServicesTableLib.h>
>>>>> #include <Library/MemoryAllocationLib.h>
>>>>> #include <Library/UefiLib.h>
>>>>> #include <Library/PrintLib.h>
>>>>> #include <Library/DebugLib.h>
>>>>> #include <Protocol/GraphicsOutput.h>
>>>>> #include <Protocol/EdidActive.h>
>>>>> 
>>>>> #define BoxWidth 100
>>>>> #define BoxHeight 100
>>>>> 
>>>>> EFI_STATUS PrintImage(EFI_HANDLE ImageHandle, UINTN ImagePositionX,
>>> UINTN
>>>>> ImagePositionY){
>>>>> 
>>>>> UINTN Size;
>>>>> EFI_STATUS Status;
>>>>> UINTN HandleIndex = 0;
>>>>> EFI_HANDLE *HandleArray = NULL;
>>>>> EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicProtocol = NULL;
>>>>> EFI_GUID gGraphicalProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
>>>>> EFI_GUID gEdidActivated = EFI_EDID_ACTIVE_PROTOCOL_GUID;
>>>>> EFI_EDID_ACTIVE_PROTOCOL *EdidActivated = NULL;
>>>>> EFI_GRAPHICS_OUTPUT_BLT_PIXEL* inMemoryImage = NULL;
>>>>> 
>>>>> Status = gBS->LocateHandleBuffer(ByProtocol,
>>>>> &gEfiGraphicsOutputProtocolGuid,
>>>>> NULL,
>>>>> &Size,
>>>>> &HandleArray);
>>>>> 
>>>>> if(!EFI_ERROR(Status))
>>>>> {
>>>>> for(HandleIndex=0; HandleIndex<Size; HandleIndex++)
>>>>> {
>>>>> 
>>>>> Status = gBS->OpenProtocol(HandleArray[HandleIndex],
>>>>> &gGraphicalProtocol,
>>>>> (VOID**) &GraphicProtocol,
>>>>> ImageHandle,
>>>>> NULL,
>>>>> EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
>>>>> 
>>>>> if(EFI_ERROR(Status)){
>>>>> 
>>>>> gBS->CloseProtocol(HandleArray[HandleIndex],
>>>>> &gGraphicalProtocol,
>>>>> ImageHandle,
>>>>> NULL);
>>>>> 
>>>>> GraphicProtocol = NULL;
>>>>> 
>>>>> continue;
>>>>> } else {
>>>>> 
>>>>> // Verifies if current handle corresponds to current video
>>>>> Status = gBS->OpenProtocol(HandleArray[HandleIndex],
>>>>> &gEdidActivated,
>>>>> (VOID**) &EdidActivated,
>>>>> ImageHandle,
>>>>> NULL,
>>>>> EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
>>>>> 
>>>>> if(EFI_ERROR(Status)){
>>>>> 
>>>>> gBS->CloseProtocol(HandleArray[HandleIndex],
>>>>> &gGraphicalProtocol,
>>>>> ImageHandle,
>>>>> NULL);
>>>>> 
>>>>> GraphicProtocol = NULL;
>>>>> 
>>>>> gBS->CloseProtocol(HandleArray[HandleIndex],
>>>>> &gEdidActivated,
>>>>> ImageHandle,
>>>>> NULL);
>>>>> 
>>>>> EdidActivated = NULL;
>>>>> 
>>>>> continue;
>>>>> } else {
>>>>> break;
>>>>> }
>>>>> }
>>>>> }
>>>>> 
>>>>> if(!EFI_ERROR(Status))
>>>>> {
>>>>> Status = gBS->AllocatePool(EfiBootServicesData,
>>>>> sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) *
>>>>> BoxWidth * BoxHeight,
>>>>> &inMemoryImage);
>>>>> 
>>>>> if(!EFI_ERROR(Status))
>>>>> {
>>>>> 
>>>>> gBS->SetMem(inMemoryImage,
>>>>> sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) *
>>>>> BoxWidth * BoxHeight,
>>>>> 0xFF);
>>>>> 
>>>>> Status = GraphicProtocol->Blt(GraphicProtocol,
>>>>> inMemoryImage,
>>>>> EfiBltBufferToVideo,
>>>>> 0,
>>>>> 0,
>>>>> ImagePositionX,
>>>>> ImagePositionY,
>>>>> BoxWidth,
>>>>> BoxHeight,
>>>>> 0);
>>>>> 
>>>>> if(EFI_ERROR(Status)){
>>>>> Print(L"Fail to print Image");
>>>>> goto CLEAR;
>>>>> }
>>>>> } else {
>>>>> Print(L"Fail to allocate buffer");
>>>>> goto CLEAR;
>>>>> }
>>>>> 
>>>>> }else{
>>>>> Print(L"Fail to locate GraphicIoProtocol devices");
>>>>> goto CLEAR;
>>>>> }
>>>>> }
>>>>> 
>>>>> CLEAR:
>>>>> 
>>>>> if(inMemoryImage != NULL) {
>>>>> FreePool(inMemoryImage);
>>>>> inMemoryImage = NULL;
>>>>> }
>>>>> 
>>>>> if(GraphicProtocol != NULL) {
>>>>> 
>>>>> Status = gBS->CloseProtocol(HandleArray[HandleIndex],
>>>>> &gGraphicalProtocol,
>>>>> ImageHandle,
>>>>> NULL);
>>>>> 
>>>>> GraphicProtocol = NULL;
>>>>> }
>>>>> 
>>>>> if(EdidActivated != NULL) {
>>>>> 
>>>>> Status = gBS->CloseProtocol(HandleArray[HandleIndex],
>>>>> &gEdidActivated,
>>>>> ImageHandle,
>>>>> NULL);
>>>>> 
>>>>> EdidActivated = NULL;
>>>>> }
>>>>> 
>>>>> if(HandleArray != NULL) {
>>>>> FreePool(HandleArray);
>>>>> HandleArray = NULL;
>>>>> }
>>>>> 
>>>>> return Status;
>>>>> }
>>>>> 
>>>>> 
>>>>> EFI_STATUS testMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE
>>>> *SystemTable)
>>>>> {
>>>>> return PrintImage(ImageHandle, 50, 50);
>>>>> }
>>>>> "
>>>>> 
>>>>> 
>>>>> Any help will be really useful.
>>>>> 
>>>>> Thanks and Regards
>>>>> Rafael R. Machado
>>>>> _______________________________________________
>>>>> edk2-devel mailing list
>>>>> [email protected]<mailto:[email protected]>
>>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>> 
>>> _______________________________________________
>>> edk2-devel mailing list
>>> [email protected]<mailto:[email protected]>
>>> https://lists.01.org/mailman/listinfo/edk2-devel
>> _______________________________________________
>> edk2-devel mailing list
>> [email protected]
>> https://lists.01.org/mailman/listinfo/edk2-devel
>> 
> _______________________________________________
> edk2-devel mailing list
> [email protected]
> https://lists.01.org/mailman/listinfo/edk2-devel

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



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

Reply via email to