mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
MdeModulePkg: Fix PeiAllocatePages() corner case
I recently ran into an AllocatePages() hang. It turns out that AllocatePages() does not account for the Memory Allocation HOB when it makes the decision of allocating out of free memory. Here is the scenario: FreeMemoryTop - 0x71C03000 FreeMemoryBottom - 0x71BDBFD8 => We have 159,784 bytes left => ~39.0098 pages left. We attempt to allocate 39 pages. There are enough pages left but allocating those pages requires to allocate a Memory Allocation HOB which needs an extra 48 bytes. But once the pages are allocated, there are only 40 bytes left. In addition to taking into account the Memory Allocation HOB size, this commit reverses the condition to keep it simple. Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
This commit is contained in:
parent
1b70dcd375
commit
996e740cc8
@ -555,6 +555,7 @@ PeiAllocatePages (
|
||||
EFI_PHYSICAL_ADDRESS *FreeMemoryTop;
|
||||
EFI_PHYSICAL_ADDRESS *FreeMemoryBottom;
|
||||
UINTN RemainingPages;
|
||||
UINTN RemainingMemory;
|
||||
UINTN Granularity;
|
||||
UINTN Padding;
|
||||
|
||||
@ -636,24 +637,18 @@ PeiAllocatePages (
|
||||
//
|
||||
// Verify that there is sufficient memory to satisfy the allocation.
|
||||
//
|
||||
RemainingPages = (UINTN)(*FreeMemoryTop - *FreeMemoryBottom) >> EFI_PAGE_SHIFT;
|
||||
RemainingMemory = (UINTN)(*FreeMemoryTop - *FreeMemoryBottom);
|
||||
RemainingPages = RemainingMemory >> EFI_PAGE_SHIFT;
|
||||
//
|
||||
// The number of remaining pages needs to be greater than or equal to that of the request pages.
|
||||
// The number of remaining pages needs to be greater than or equal to that of
|
||||
// the request pages. In addition, there should be enough space left to hold a
|
||||
// Memory Allocation HOB.
|
||||
//
|
||||
Pages = ALIGN_VALUE (Pages, EFI_SIZE_TO_PAGES (Granularity));
|
||||
if (RemainingPages < Pages) {
|
||||
//
|
||||
// Try to find free memory by searching memory allocation HOBs.
|
||||
//
|
||||
Status = FindFreeMemoryFromMemoryAllocationHob (MemoryType, Pages, Granularity, Memory);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_ERROR, "AllocatePages failed: No 0x%lx Pages is available.\n", (UINT64)Pages));
|
||||
DEBUG ((DEBUG_ERROR, "There is only left 0x%lx pages memory resource to be allocated.\n", (UINT64)RemainingPages));
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
} else {
|
||||
if ((RemainingPages > Pages) ||
|
||||
((RemainingPages == Pages) &&
|
||||
((RemainingMemory & EFI_PAGE_MASK) >= sizeof (EFI_HOB_MEMORY_ALLOCATION))))
|
||||
{
|
||||
//
|
||||
// Update the PHIT to reflect the memory usage
|
||||
//
|
||||
@ -674,6 +669,18 @@ PeiAllocatePages (
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
//
|
||||
// Try to find free memory by searching memory allocation HOBs.
|
||||
//
|
||||
Status = FindFreeMemoryFromMemoryAllocationHob (MemoryType, Pages, Granularity, Memory);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_ERROR, "AllocatePages failed: No 0x%lx Pages is available.\n", (UINT64)Pages));
|
||||
DEBUG ((DEBUG_ERROR, "There is only left 0x%lx pages memory resource to be allocated.\n", (UINT64)RemainingPages));
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user