Amazing explanation Aaron!! Thanks a lot!! Rafael R. Machado
Em qua, 1 de jun de 2016 às 15:29, <aaron....@congatec.com> escreveu: > 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 <af...@apple.com> > To: Rafael Machado <rafaelrodrigues.mach...@gmail.com> > Cc: "Carsey, Jaben" <jaben.car...@intel.com>, " > edk2-devel@lists.01.org" <edk2-devel@lists.01.org> > Date: 06/01/2016 11:16 AM > Subject: Re: [edk2] Memory Consumption after BLT (GOP) > Sent by: "edk2-devel" <edk2-devel-boun...@lists.01.org> > ------------------------------ > > > > > > On Jun 1, 2016, at 11:10 AM, Rafael Machado < > rafaelrodrigues.mach...@gmail.com> 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 <jaben.car...@intel.com > > > > 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:rafaelrodrigues.mach...@gmail.com > <rafaelrodrigues.mach...@gmail.com>] > >> Sent: Wednesday, June 01, 2016 11:00 AM > >> To: Carsey, Jaben <jaben.car...@intel.com> > >> Cc: edk2-devel@lists.01.org > >> 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 < > jaben.car...@intel.com > >> <mailto:jaben.car...@intel.com <jaben.car...@intel.com>>> 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:edk2-devel-boun...@lists.01.org > <edk2-devel-boun...@lists.01.org><mailto: > >> edk2-devel-boun...@lists.01.org>] On Behalf Of > >>> Rafael Machado > >>> Sent: Wednesday, June 01, 2016 10:33 AM > >>> To: Carsey, Jaben <jaben.car...@intel.com< > mailto:jaben.car...@intel.com <jaben.car...@intel.com> > >>>> > >>> Cc: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org > <edk2-devel@lists.01.org>> > >>> 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 < > jaben.car...@intel.com > >> <mailto:jaben.car...@intel.com <jaben.car...@intel.com>>> > >>> 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 < > >>>> rafaelrodrigues.mach...@gmail.com<mailto: > >> rafaelrodrigues.mach...@gmail.com>> 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 > >>>>> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org > <edk2-devel@lists.01.org>> > >>>>> https://lists.01.org/mailman/listinfo/edk2-devel > >>>> > >>> _______________________________________________ > >>> edk2-devel mailing list > >>> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org > <edk2-devel@lists.01.org>> > >>> https://lists.01.org/mailman/listinfo/edk2-devel > >> _______________________________________________ > >> edk2-devel mailing list > >> edk2-devel@lists.01.org > >> https://lists.01.org/mailman/listinfo/edk2-devel > >> > > _______________________________________________ > > edk2-devel mailing list > > edk2-devel@lists.01.org > > https://lists.01.org/mailman/listinfo/edk2-devel > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel > > > _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel