From: Jiaqi Gao <jiaqi.gao@intel.com>
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3937
When CoreAllocatePages() / CoreAllocatePool() meets error of
EFI_OUT_OF_RESOURCES, locate the EdkiiMemoryAcceptProtocol and accept extra
memory dynamically.
Firstly, find the unaccpeted memory region with enough size in GCD
entries. Then locate the EdkiiMemoryAcceptProtocol and accept the memory.
Finally, update the GCD memory and gMemoryMap entries.
After updating the memory infomation, CoreInternalAllocatePages() /
CoreInternalAllocatePool() will be recalled to allocate pages / pool.
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Jiaqi Gao <jiaqi.gao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
MdeModulePkg/Core/Dxe/DxeMain.inf | 1 +
MdeModulePkg/Core/Dxe/Mem/Imem.h | 16 +++
MdeModulePkg/Core/Dxe/Mem/Page.c | 190 ++++++++++++++++++++++++++++++
MdeModulePkg/Core/Dxe/Mem/Pool.c | 14 +++
4 files changed, 221 insertions(+)
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index e4bca895773d..371ba45357be 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -169,6 +169,7 @@
gEfiVariableArchProtocolGuid ## CONSUMES
gEfiCapsuleArchProtocolGuid ## CONSUMES
gEfiWatchdogTimerArchProtocolGuid ## CONSUMES
+ gEdkiiMemoryAcceptProtocolGuid ## CONSUMES
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber ## SOMETIMES_CONSUMES
diff --git a/MdeModulePkg/Core/Dxe/Mem/Imem.h b/MdeModulePkg/Core/Dxe/Mem/Imem.h
index 2f0bf2bf631f..22e0d0e44030 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Imem.h
+++ b/MdeModulePkg/Core/Dxe/Mem/Imem.h
@@ -47,6 +47,22 @@ typedef struct {
// Internal prototypes
//
+/**
+ Internal function. Used by the pool and page functions to accept memory
+ when OOM occurs.
+
+ @param Type The type of allocation to perform.
+ @param AcceptSize Size of memory to be accepted.
+ @param Memory Accept memory address
+
+**/
+EFI_STATUS
+AcceptMemoryResource (
+ IN EFI_ALLOCATE_TYPE Type,
+ IN UINTN AcceptSize,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+ );
+
/**
Internal function. Used by the pool functions to allocate pages
to back pool allocation requests.
diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c
index 160289c1f9ec..513792a7fe04 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Page.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
@@ -10,6 +10,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "Imem.h"
#include "HeapGuard.h"
#include <Pi/PrePiDxeCis.h>
+#include <Protocol/MemoryAccept.h>
//
// Entry for tracking the memory regions for each memory type to coalesce similar memory types
@@ -379,6 +380,176 @@ CoreFreeMemoryMapStack (
mFreeMapStack -= 1;
}
+/**
+ Used to accept memory when OOM occurs.
+
+ @param Type The type of allocation to perform.
+ @param AcceptSize Size of memory to be accepted.
+ @param Memory Accept memory address
+
+**/
+EFI_STATUS
+AcceptMemoryResource (
+ IN EFI_ALLOCATE_TYPE Type,
+ IN UINTN AcceptSize,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+{
+ #ifdef MDE_CPU_X64
+
+ LIST_ENTRY *Link;
+ EFI_GCD_MAP_ENTRY *GcdEntry;
+ EFI_GCD_MAP_ENTRY UnacceptedEntry;
+ EDKII_MEMORY_ACCEPT_PROTOCOL *MemoryAcceptProtocol;
+ UINTN Start;
+ UINTN End;
+ EFI_STATUS Status;
+
+ //
+ // We accept n*32MB at one time to improve the efficiency.
+ //
+ AcceptSize = (AcceptSize + SIZE_32MB - 1) & ~(SIZE_32MB - 1);
+
+ if (AcceptSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->LocateProtocol (&gEdkiiMemoryAcceptProtocolGuid, NULL, (VOID **)&MemoryAcceptProtocol);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Type == AllocateAddress) {
+ Start = *Memory;
+ End = *Memory + AcceptSize;
+ }
+
+ if (Type == AllocateMaxAddress) {
+ if (*Memory < EFI_PAGE_MASK) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((*Memory & EFI_PAGE_MASK) != EFI_PAGE_MASK) {
+ //
+ // Change MaxAddress to be 1 page lower
+ //
+ *Memory -= EFI_PAGE_SIZE;
+
+ //
+ // Set MaxAddress to a page boundary
+ //
+ *Memory &= ~(UINT64)EFI_PAGE_MASK;
+
+ //
+ // Set MaxAddress to end of the page
+ //
+ *Memory |= EFI_PAGE_MASK;
+ }
+ }
+
+ //
+ // Traverse the mGcdMemorySpaceMap to find out the unaccepted
+ // memory entry with big enough size.
+ //
+ Link = mGcdMemorySpaceMap.ForwardLink;
+ while (Link != &mGcdMemorySpaceMap) {
+ GcdEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ if (GcdEntry->GcdMemoryType == EFI_GCD_MEMORY_TYPE_UNACCEPTED) {
+ if (Type == AllocateMaxAddress) {
+ if (GcdEntry->BaseAddress + AcceptSize - 1 > *Memory) {
+ Link = Link->ForwardLink;
+ continue;
+ }
+ } else if (Type == AllocateAddress) {
+ if ((GcdEntry->BaseAddress > *Memory) || (GcdEntry->EndAddress < *Memory + AcceptSize - 1)) {
+ Link = Link->ForwardLink;
+ continue;
+ }
+ }
+
+ //
+ // Is the entry big enough?
+ //
+ if (AcceptSize <= GcdEntry->EndAddress - GcdEntry->BaseAddress + 1) {
+ UnacceptedEntry = *GcdEntry;
+ if (Type != AllocateAddress) {
+ Start = UnacceptedEntry.BaseAddress;
+ End = UnacceptedEntry.BaseAddress + AcceptSize - 1;
+ }
+
+ break;
+ }
+ }
+
+ Link = Link->ForwardLink;
+ }
+
+ if (Link == &mGcdMemorySpaceMap) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Accept memory using the interface provide by the protocol.
+ //
+ Status = MemoryAcceptProtocol->AcceptMemory (MemoryAcceptProtocol, Start, AcceptSize);
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // If memory is accepted successfully, remove the target memory space from GCD.
+ //
+ CoreRemoveMemorySpace (UnacceptedEntry.BaseAddress, UnacceptedEntry.EndAddress - UnacceptedEntry.BaseAddress + 1);
+
+ //
+ // Add the remain lower part of unaccepted memory to the
+ // Gcd memory space and memory map.
+ //
+ if (Start > UnacceptedEntry.BaseAddress) {
+ CoreAddMemorySpace (
+ EFI_GCD_MEMORY_TYPE_UNACCEPTED,
+ UnacceptedEntry.BaseAddress,
+ Start - UnacceptedEntry.BaseAddress,
+ UnacceptedEntry.Capabilities
+ );
+ }
+
+ //
+ // Update accepted part of the memory entry to type of EfiGcdMemoryTypeSystemMemory
+ // and add the range to the memory map.
+ //
+ CoreAddMemorySpace (
+ EfiGcdMemoryTypeSystemMemory,
+ Start,
+ AcceptSize,
+ //
+ // Hardcode memory space attributes.
+ //
+ EFI_MEMORY_CPU_CRYPTO | EFI_MEMORY_XP | EFI_MEMORY_RO | EFI_MEMORY_RP
+ );
+
+ //
+ // Add the remain higher part of unaccepted memory to the
+ // Gcd memory space and memory map.
+ //
+ if (UnacceptedEntry.EndAddress > End) {
+ CoreAddMemorySpace (
+ EFI_GCD_MEMORY_TYPE_UNACCEPTED,
+ End + 1,
+ UnacceptedEntry.EndAddress - End,
+ UnacceptedEntry.Capabilities
+ );
+ }
+
+ return EFI_SUCCESS;
+
+ #else
+
+ return EFI_UNSUPPORTED;
+
+ #endif
+}
+
/**
Find untested but initialized memory regions in GCD map and convert them to be DXE allocatable.
@@ -1486,6 +1657,25 @@ CoreAllocatePages (
Memory,
NeedGuard
);
+ #ifdef MDE_CPU_X64
+
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ Status = AcceptMemoryResource (Type, NumberOfPages << EFI_PAGE_SHIFT, Memory);
+ if (!EFI_ERROR (Status)) {
+ Status = CoreInternalAllocatePages (
+ Type,
+ MemoryType,
+ NumberOfPages,
+ Memory,
+ NeedGuard
+ );
+ } else {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ #endif
+
if (!EFI_ERROR (Status)) {
CoreUpdateProfile (
(EFI_PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c
index 7aaf501600cf..9e8c8611c1ef 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Pool.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c
@@ -273,6 +273,20 @@ CoreAllocatePool (
EFI_STATUS Status;
Status = CoreInternalAllocatePool (PoolType, Size, Buffer);
+
+ #ifdef MDE_CPU_X64
+
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ Status = AcceptMemoryResource (AllocateAnyPages, Size, NULL);
+ if (!EFI_ERROR (Status)) {
+ Status = CoreInternalAllocatePool (PoolType, Size, Buffer);
+ } else {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ #endif
+
if (!EFI_ERROR (Status)) {
CoreUpdateProfile (
(EFI_PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
--
2.29.2.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#92893): https://edk2.groups.io/g/devel/message/92893
Mute This Topic: https://groups.io/mt/93285612/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
On 8/27/22 01:21, Min Xu wrote:
> From: Jiaqi Gao <jiaqi.gao@intel.com>
>
> RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3937
>
> When CoreAllocatePages() / CoreAllocatePool() meets error of
> EFI_OUT_OF_RESOURCES, locate the EdkiiMemoryAcceptProtocol and accept extra
> memory dynamically.
>
> Firstly, find the unaccpeted memory region with enough size in GCD
s/unaccpeted/unaccepted/
> entries. Then locate the EdkiiMemoryAcceptProtocol and accept the memory.
> Finally, update the GCD memory and gMemoryMap entries.
>
> After updating the memory infomation, CoreInternalAllocatePages() /
> CoreInternalAllocatePool() will be recalled to allocate pages / pool.
What path does allocation take when called through boot services? If I set
a 256MB accepted memory size, I can get to the bootloader and select my
kernel. But then the kernel dies in efi_relocate_kernel() with:
EFI stub: ERROR: Failed to allocate usable memory for kernel.
EFI stub: ERROR: efi_relocate_kernel() failed!
EFI stub: ERROR: efi_main() failed!
because both efi_bs_call(allocate_pages, ...) and efi_low_alloc_above() fail.
Similar to DXE, should OVMF accept more memory through this path to let
the kernel boot?
Thanks,
Tom
>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Dandan Bi <dandan.bi@intel.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Jiaqi Gao <jiaqi.gao@intel.com>
> Signed-off-by: Min Xu <min.m.xu@intel.com>
> ---
> MdeModulePkg/Core/Dxe/DxeMain.inf | 1 +
> MdeModulePkg/Core/Dxe/Mem/Imem.h | 16 +++
> MdeModulePkg/Core/Dxe/Mem/Page.c | 190 ++++++++++++++++++++++++++++++
> MdeModulePkg/Core/Dxe/Mem/Pool.c | 14 +++
> 4 files changed, 221 insertions(+)
>
> diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
> index e4bca895773d..371ba45357be 100644
> --- a/MdeModulePkg/Core/Dxe/DxeMain.inf
> +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
> @@ -169,6 +169,7 @@
> gEfiVariableArchProtocolGuid ## CONSUMES
> gEfiCapsuleArchProtocolGuid ## CONSUMES
> gEfiWatchdogTimerArchProtocolGuid ## CONSUMES
> + gEdkiiMemoryAcceptProtocolGuid ## CONSUMES
>
> [Pcd]
> gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber ## SOMETIMES_CONSUMES
> diff --git a/MdeModulePkg/Core/Dxe/Mem/Imem.h b/MdeModulePkg/Core/Dxe/Mem/Imem.h
> index 2f0bf2bf631f..22e0d0e44030 100644
> --- a/MdeModulePkg/Core/Dxe/Mem/Imem.h
> +++ b/MdeModulePkg/Core/Dxe/Mem/Imem.h
> @@ -47,6 +47,22 @@ typedef struct {
> // Internal prototypes
> //
>
> +/**
> + Internal function. Used by the pool and page functions to accept memory
> + when OOM occurs.
> +
> + @param Type The type of allocation to perform.
> + @param AcceptSize Size of memory to be accepted.
> + @param Memory Accept memory address
> +
> +**/
> +EFI_STATUS
> +AcceptMemoryResource (
> + IN EFI_ALLOCATE_TYPE Type,
> + IN UINTN AcceptSize,
> + IN OUT EFI_PHYSICAL_ADDRESS *Memory
> + );
> +
> /**
> Internal function. Used by the pool functions to allocate pages
> to back pool allocation requests.
> diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c
> index 160289c1f9ec..513792a7fe04 100644
> --- a/MdeModulePkg/Core/Dxe/Mem/Page.c
> +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
> @@ -10,6 +10,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> #include "Imem.h"
> #include "HeapGuard.h"
> #include <Pi/PrePiDxeCis.h>
> +#include <Protocol/MemoryAccept.h>
>
> //
> // Entry for tracking the memory regions for each memory type to coalesce similar memory types
> @@ -379,6 +380,176 @@ CoreFreeMemoryMapStack (
> mFreeMapStack -= 1;
> }
>
> +/**
> + Used to accept memory when OOM occurs.
> +
> + @param Type The type of allocation to perform.
> + @param AcceptSize Size of memory to be accepted.
> + @param Memory Accept memory address
> +
> +**/
> +EFI_STATUS
> +AcceptMemoryResource (
> + IN EFI_ALLOCATE_TYPE Type,
> + IN UINTN AcceptSize,
> + IN OUT EFI_PHYSICAL_ADDRESS *Memory
> + )
> +{
> + #ifdef MDE_CPU_X64
> +
> + LIST_ENTRY *Link;
> + EFI_GCD_MAP_ENTRY *GcdEntry;
> + EFI_GCD_MAP_ENTRY UnacceptedEntry;
> + EDKII_MEMORY_ACCEPT_PROTOCOL *MemoryAcceptProtocol;
> + UINTN Start;
> + UINTN End;
> + EFI_STATUS Status;
> +
> + //
> + // We accept n*32MB at one time to improve the efficiency.
> + //
> + AcceptSize = (AcceptSize + SIZE_32MB - 1) & ~(SIZE_32MB - 1);
> +
> + if (AcceptSize == 0) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = gBS->LocateProtocol (&gEdkiiMemoryAcceptProtocolGuid, NULL, (VOID **)&MemoryAcceptProtocol);
> + if (EFI_ERROR (Status)) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + if (Type == AllocateAddress) {
> + Start = *Memory;
> + End = *Memory + AcceptSize;
> + }
> +
> + if (Type == AllocateMaxAddress) {
> + if (*Memory < EFI_PAGE_MASK) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if ((*Memory & EFI_PAGE_MASK) != EFI_PAGE_MASK) {
> + //
> + // Change MaxAddress to be 1 page lower
> + //
> + *Memory -= EFI_PAGE_SIZE;
> +
> + //
> + // Set MaxAddress to a page boundary
> + //
> + *Memory &= ~(UINT64)EFI_PAGE_MASK;
> +
> + //
> + // Set MaxAddress to end of the page
> + //
> + *Memory |= EFI_PAGE_MASK;
> + }
> + }
> +
> + //
> + // Traverse the mGcdMemorySpaceMap to find out the unaccepted
> + // memory entry with big enough size.
> + //
> + Link = mGcdMemorySpaceMap.ForwardLink;
> + while (Link != &mGcdMemorySpaceMap) {
> + GcdEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
> + if (GcdEntry->GcdMemoryType == EFI_GCD_MEMORY_TYPE_UNACCEPTED) {
> + if (Type == AllocateMaxAddress) {
> + if (GcdEntry->BaseAddress + AcceptSize - 1 > *Memory) {
> + Link = Link->ForwardLink;
> + continue;
> + }
> + } else if (Type == AllocateAddress) {
> + if ((GcdEntry->BaseAddress > *Memory) || (GcdEntry->EndAddress < *Memory + AcceptSize - 1)) {
> + Link = Link->ForwardLink;
> + continue;
> + }
> + }
> +
> + //
> + // Is the entry big enough?
> + //
> + if (AcceptSize <= GcdEntry->EndAddress - GcdEntry->BaseAddress + 1) {
> + UnacceptedEntry = *GcdEntry;
> + if (Type != AllocateAddress) {
> + Start = UnacceptedEntry.BaseAddress;
> + End = UnacceptedEntry.BaseAddress + AcceptSize - 1;
> + }
> +
> + break;
> + }
> + }
> +
> + Link = Link->ForwardLink;
> + }
> +
> + if (Link == &mGcdMemorySpaceMap) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Accept memory using the interface provide by the protocol.
> + //
> + Status = MemoryAcceptProtocol->AcceptMemory (MemoryAcceptProtocol, Start, AcceptSize);
> + if (EFI_ERROR (Status)) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // If memory is accepted successfully, remove the target memory space from GCD.
> + //
> + CoreRemoveMemorySpace (UnacceptedEntry.BaseAddress, UnacceptedEntry.EndAddress - UnacceptedEntry.BaseAddress + 1);
> +
> + //
> + // Add the remain lower part of unaccepted memory to the
> + // Gcd memory space and memory map.
> + //
> + if (Start > UnacceptedEntry.BaseAddress) {
> + CoreAddMemorySpace (
> + EFI_GCD_MEMORY_TYPE_UNACCEPTED,
> + UnacceptedEntry.BaseAddress,
> + Start - UnacceptedEntry.BaseAddress,
> + UnacceptedEntry.Capabilities
> + );
> + }
> +
> + //
> + // Update accepted part of the memory entry to type of EfiGcdMemoryTypeSystemMemory
> + // and add the range to the memory map.
> + //
> + CoreAddMemorySpace (
> + EfiGcdMemoryTypeSystemMemory,
> + Start,
> + AcceptSize,
> + //
> + // Hardcode memory space attributes.
> + //
> + EFI_MEMORY_CPU_CRYPTO | EFI_MEMORY_XP | EFI_MEMORY_RO | EFI_MEMORY_RP
> + );
> +
> + //
> + // Add the remain higher part of unaccepted memory to the
> + // Gcd memory space and memory map.
> + //
> + if (UnacceptedEntry.EndAddress > End) {
> + CoreAddMemorySpace (
> + EFI_GCD_MEMORY_TYPE_UNACCEPTED,
> + End + 1,
> + UnacceptedEntry.EndAddress - End,
> + UnacceptedEntry.Capabilities
> + );
> + }
> +
> + return EFI_SUCCESS;
> +
> + #else
> +
> + return EFI_UNSUPPORTED;
> +
> + #endif
> +}
> +
> /**
> Find untested but initialized memory regions in GCD map and convert them to be DXE allocatable.
>
> @@ -1486,6 +1657,25 @@ CoreAllocatePages (
> Memory,
> NeedGuard
> );
> + #ifdef MDE_CPU_X64
> +
> + if (Status == EFI_OUT_OF_RESOURCES) {
> + Status = AcceptMemoryResource (Type, NumberOfPages << EFI_PAGE_SHIFT, Memory);
> + if (!EFI_ERROR (Status)) {
> + Status = CoreInternalAllocatePages (
> + Type,
> + MemoryType,
> + NumberOfPages,
> + Memory,
> + NeedGuard
> + );
> + } else {
> + Status = EFI_OUT_OF_RESOURCES;
> + }
> + }
> +
> + #endif
> +
> if (!EFI_ERROR (Status)) {
> CoreUpdateProfile (
> (EFI_PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
> diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c
> index 7aaf501600cf..9e8c8611c1ef 100644
> --- a/MdeModulePkg/Core/Dxe/Mem/Pool.c
> +++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c
> @@ -273,6 +273,20 @@ CoreAllocatePool (
> EFI_STATUS Status;
>
> Status = CoreInternalAllocatePool (PoolType, Size, Buffer);
> +
> + #ifdef MDE_CPU_X64
> +
> + if (Status == EFI_OUT_OF_RESOURCES) {
> + Status = AcceptMemoryResource (AllocateAnyPages, Size, NULL);
> + if (!EFI_ERROR (Status)) {
> + Status = CoreInternalAllocatePool (PoolType, Size, Buffer);
> + } else {
> + Status = EFI_OUT_OF_RESOURCES;
> + }
> + }
> +
> + #endif
> +
> if (!EFI_ERROR (Status)) {
> CoreUpdateProfile (
> (EFI_PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#92925): https://edk2.groups.io/g/devel/message/92925
Mute This Topic: https://groups.io/mt/93285612/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
On August 30, 2022 4:47 AM, Lendacky, Thomas wrote: > On 8/27/22 01:21, Min Xu wrote: > > From: Jiaqi Gao <jiaqi.gao@intel.com> > > > > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3937 > > > > When CoreAllocatePages() / CoreAllocatePool() meets error of > > EFI_OUT_OF_RESOURCES, locate the EdkiiMemoryAcceptProtocol and > accept > > extra memory dynamically. > > > > Firstly, find the unaccpeted memory region with enough size in GCD > > s/unaccpeted/unaccepted/ Thanks for reminder. It will be fixed in the next version. > > > entries. Then locate the EdkiiMemoryAcceptProtocol and accept the memory. > > Finally, update the GCD memory and gMemoryMap entries. > > > > After updating the memory infomation, CoreInternalAllocatePages() / > > CoreInternalAllocatePool() will be recalled to allocate pages / pool. > > What path does allocation take when called through boot services? If I set a > 256MB accepted memory size, I can get to the bootloader and select my kernel. > But then the kernel dies in efi_relocate_kernel() with: > > EFI stub: ERROR: Failed to allocate usable memory for kernel. > EFI stub: ERROR: efi_relocate_kernel() failed! > EFI stub: ERROR: efi_main() failed! > > because both efi_bs_call(allocate_pages, ...) and efi_low_alloc_above() fail. > > Similar to DXE, should OVMF accept more memory through this path to let the > kernel boot? > Tom is using the grub boot, right? In this case, 256MB accepted memory size is too small. Because in grub boot, AllocatePages is called to allocate memory in grub boot. The allocation type is AllocateMaxAddress and the memory address is 100000. It means the memory should be allocated below 0x100000. If only 256MB is accepted, then probably this memory region (which is under 0x100000) has been used. And there is no unaccepted memory region which is available for this memory region (which is under 0x100000). I tried 256MB and it works for direct boot, but not for grub boot. I tried 384MB and it works for both grub boot and direct boot. So my suggestion is that the minimal accept memory size is 384MB or more. Thanks Min -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92951): https://edk2.groups.io/g/devel/message/92951 Mute This Topic: https://groups.io/mt/93285612/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
On 8/29/22 22:20, Xu, Min M wrote: > On August 30, 2022 4:47 AM, Lendacky, Thomas wrote: >> On 8/27/22 01:21, Min Xu wrote: >>> From: Jiaqi Gao <jiaqi.gao@intel.com> >>> >>> RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3937 >>> >>> When CoreAllocatePages() / CoreAllocatePool() meets error of >>> EFI_OUT_OF_RESOURCES, locate the EdkiiMemoryAcceptProtocol and >> accept >>> extra memory dynamically. >>> >>> Firstly, find the unaccpeted memory region with enough size in GCD >> >> s/unaccpeted/unaccepted/ > Thanks for reminder. It will be fixed in the next version. >> >>> entries. Then locate the EdkiiMemoryAcceptProtocol and accept the memory. >>> Finally, update the GCD memory and gMemoryMap entries. >>> >>> After updating the memory infomation, CoreInternalAllocatePages() / >>> CoreInternalAllocatePool() will be recalled to allocate pages / pool. >> >> What path does allocation take when called through boot services? If I set a >> 256MB accepted memory size, I can get to the bootloader and select my kernel. >> But then the kernel dies in efi_relocate_kernel() with: >> >> EFI stub: ERROR: Failed to allocate usable memory for kernel. >> EFI stub: ERROR: efi_relocate_kernel() failed! >> EFI stub: ERROR: efi_main() failed! >> >> because both efi_bs_call(allocate_pages, ...) and efi_low_alloc_above() fail. >> >> Similar to DXE, should OVMF accept more memory through this path to let the >> kernel boot? >> > Tom is using the grub boot, right? In this case, 256MB accepted memory size is too small. > Because in grub boot, AllocatePages is called to allocate memory in grub boot. The allocation type is AllocateMaxAddress and the memory address is 100000. It means the memory should be allocated below 0x100000. > If only 256MB is accepted, then probably this memory region (which is under 0x100000) has been used. And there is no unaccepted memory region which is available for this memory region (which is under 0x100000). > I tried 256MB and it works for direct boot, but not for grub boot. > I tried 384MB and it works for both grub boot and direct boot. > So my suggestion is that the minimal accept memory size is 384MB or more. Right, I've been able to boot with 512MB without issues. The address is 0x1000000 (16MB) and so that makes sense, nothing that can be done for that situation. Thanks, Tom > > Thanks > Min -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92980): https://edk2.groups.io/g/devel/message/92980 Mute This Topic: https://groups.io/mt/93285612/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
Can you please explain more about this patch?
I am a little nervous when seeing patches that change the fundamental memory services.
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Lendacky, Thomas via groups.io
> Sent: Tuesday, August 30, 2022 4:47 AM
> To: Xu, Min M <min.m.xu@intel.com>; devel@edk2.groups.io
> Cc: Gao, Jiaqi <jiaqi.gao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Bi,
> Dandan <dandan.bi@intel.com>; Aktas, Erdem <erdemaktas@google.com>; James Bottomley <jejb@linux.ibm.com>; Yao,
> Jiewen <jiewen.yao@intel.com>; Gerd Hoffmann <kraxel@redhat.com>
> Subject: Re: [edk2-devel] [PATCH V2 14/14] MdeModulePkg: Pool and page functions accept memory when OOM occurs
>
> On 8/27/22 01:21, Min Xu wrote:
> > From: Jiaqi Gao <jiaqi.gao@intel.com>
> >
> > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3937
> >
> > When CoreAllocatePages() / CoreAllocatePool() meets error of
> > EFI_OUT_OF_RESOURCES, locate the EdkiiMemoryAcceptProtocol and accept extra
> > memory dynamically.
> >
> > Firstly, find the unaccpeted memory region with enough size in GCD
>
> s/unaccpeted/unaccepted/
>
> > entries. Then locate the EdkiiMemoryAcceptProtocol and accept the memory.
> > Finally, update the GCD memory and gMemoryMap entries.
> >
> > After updating the memory infomation, CoreInternalAllocatePages() /
> > CoreInternalAllocatePool() will be recalled to allocate pages / pool.
>
> What path does allocation take when called through boot services? If I set
> a 256MB accepted memory size, I can get to the bootloader and select my
> kernel. But then the kernel dies in efi_relocate_kernel() with:
>
> EFI stub: ERROR: Failed to allocate usable memory for kernel.
> EFI stub: ERROR: efi_relocate_kernel() failed!
> EFI stub: ERROR: efi_main() failed!
>
> because both efi_bs_call(allocate_pages, ...) and efi_low_alloc_above() fail.
>
> Similar to DXE, should OVMF accept more memory through this path to let
> the kernel boot?
>
> Thanks,
> Tom
>
> >
> > Cc: Jian J Wang <jian.j.wang@intel.com>
> > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > Cc: Dandan Bi <dandan.bi@intel.com>
> > Cc: Erdem Aktas <erdemaktas@google.com>
> > Cc: James Bottomley <jejb@linux.ibm.com>
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Tom Lendacky <thomas.lendacky@amd.com>
> > Cc: Gerd Hoffmann <kraxel@redhat.com>
> > Signed-off-by: Jiaqi Gao <jiaqi.gao@intel.com>
> > Signed-off-by: Min Xu <min.m.xu@intel.com>
> > ---
> > MdeModulePkg/Core/Dxe/DxeMain.inf | 1 +
> > MdeModulePkg/Core/Dxe/Mem/Imem.h | 16 +++
> > MdeModulePkg/Core/Dxe/Mem/Page.c | 190 ++++++++++++++++++++++++++++++
> > MdeModulePkg/Core/Dxe/Mem/Pool.c | 14 +++
> > 4 files changed, 221 insertions(+)
> >
> > diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
> > index e4bca895773d..371ba45357be 100644
> > --- a/MdeModulePkg/Core/Dxe/DxeMain.inf
> > +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
> > @@ -169,6 +169,7 @@
> > gEfiVariableArchProtocolGuid ## CONSUMES
> > gEfiCapsuleArchProtocolGuid ## CONSUMES
> > gEfiWatchdogTimerArchProtocolGuid ## CONSUMES
> > + gEdkiiMemoryAcceptProtocolGuid ## CONSUMES
> >
> > [Pcd]
> > gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber ## SOMETIMES_CONSUMES
> > diff --git a/MdeModulePkg/Core/Dxe/Mem/Imem.h b/MdeModulePkg/Core/Dxe/Mem/Imem.h
> > index 2f0bf2bf631f..22e0d0e44030 100644
> > --- a/MdeModulePkg/Core/Dxe/Mem/Imem.h
> > +++ b/MdeModulePkg/Core/Dxe/Mem/Imem.h
> > @@ -47,6 +47,22 @@ typedef struct {
> > // Internal prototypes
> > //
> >
> > +/**
> > + Internal function. Used by the pool and page functions to accept memory
> > + when OOM occurs.
> > +
> > + @param Type The type of allocation to perform.
> > + @param AcceptSize Size of memory to be accepted.
> > + @param Memory Accept memory address
> > +
> > +**/
> > +EFI_STATUS
> > +AcceptMemoryResource (
> > + IN EFI_ALLOCATE_TYPE Type,
> > + IN UINTN AcceptSize,
> > + IN OUT EFI_PHYSICAL_ADDRESS *Memory
> > + );
> > +
> > /**
> > Internal function. Used by the pool functions to allocate pages
> > to back pool allocation requests.
> > diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c
> > index 160289c1f9ec..513792a7fe04 100644
> > --- a/MdeModulePkg/Core/Dxe/Mem/Page.c
> > +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
> > @@ -10,6 +10,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > #include "Imem.h"
> > #include "HeapGuard.h"
> > #include <Pi/PrePiDxeCis.h>
> > +#include <Protocol/MemoryAccept.h>
> >
> > //
> > // Entry for tracking the memory regions for each memory type to coalesce similar memory types
> > @@ -379,6 +380,176 @@ CoreFreeMemoryMapStack (
> > mFreeMapStack -= 1;
> > }
> >
> > +/**
> > + Used to accept memory when OOM occurs.
> > +
> > + @param Type The type of allocation to perform.
> > + @param AcceptSize Size of memory to be accepted.
> > + @param Memory Accept memory address
> > +
> > +**/
> > +EFI_STATUS
> > +AcceptMemoryResource (
> > + IN EFI_ALLOCATE_TYPE Type,
> > + IN UINTN AcceptSize,
> > + IN OUT EFI_PHYSICAL_ADDRESS *Memory
> > + )
> > +{
> > + #ifdef MDE_CPU_X64
> > +
> > + LIST_ENTRY *Link;
> > + EFI_GCD_MAP_ENTRY *GcdEntry;
> > + EFI_GCD_MAP_ENTRY UnacceptedEntry;
> > + EDKII_MEMORY_ACCEPT_PROTOCOL *MemoryAcceptProtocol;
> > + UINTN Start;
> > + UINTN End;
> > + EFI_STATUS Status;
> > +
> > + //
> > + // We accept n*32MB at one time to improve the efficiency.
> > + //
> > + AcceptSize = (AcceptSize + SIZE_32MB - 1) & ~(SIZE_32MB - 1);
> > +
> > + if (AcceptSize == 0) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + Status = gBS->LocateProtocol (&gEdkiiMemoryAcceptProtocolGuid, NULL, (VOID **)&MemoryAcceptProtocol);
> > + if (EFI_ERROR (Status)) {
> > + return EFI_UNSUPPORTED;
> > + }
> > +
> > + if (Type == AllocateAddress) {
> > + Start = *Memory;
> > + End = *Memory + AcceptSize;
> > + }
> > +
> > + if (Type == AllocateMaxAddress) {
> > + if (*Memory < EFI_PAGE_MASK) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + if ((*Memory & EFI_PAGE_MASK) != EFI_PAGE_MASK) {
> > + //
> > + // Change MaxAddress to be 1 page lower
> > + //
> > + *Memory -= EFI_PAGE_SIZE;
> > +
> > + //
> > + // Set MaxAddress to a page boundary
> > + //
> > + *Memory &= ~(UINT64)EFI_PAGE_MASK;
> > +
> > + //
> > + // Set MaxAddress to end of the page
> > + //
> > + *Memory |= EFI_PAGE_MASK;
> > + }
> > + }
> > +
> > + //
> > + // Traverse the mGcdMemorySpaceMap to find out the unaccepted
> > + // memory entry with big enough size.
> > + //
> > + Link = mGcdMemorySpaceMap.ForwardLink;
> > + while (Link != &mGcdMemorySpaceMap) {
> > + GcdEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
> > + if (GcdEntry->GcdMemoryType == EFI_GCD_MEMORY_TYPE_UNACCEPTED) {
> > + if (Type == AllocateMaxAddress) {
> > + if (GcdEntry->BaseAddress + AcceptSize - 1 > *Memory) {
> > + Link = Link->ForwardLink;
> > + continue;
> > + }
> > + } else if (Type == AllocateAddress) {
> > + if ((GcdEntry->BaseAddress > *Memory) || (GcdEntry->EndAddress < *Memory + AcceptSize - 1)) {
> > + Link = Link->ForwardLink;
> > + continue;
> > + }
> > + }
> > +
> > + //
> > + // Is the entry big enough?
> > + //
> > + if (AcceptSize <= GcdEntry->EndAddress - GcdEntry->BaseAddress + 1) {
> > + UnacceptedEntry = *GcdEntry;
> > + if (Type != AllocateAddress) {
> > + Start = UnacceptedEntry.BaseAddress;
> > + End = UnacceptedEntry.BaseAddress + AcceptSize - 1;
> > + }
> > +
> > + break;
> > + }
> > + }
> > +
> > + Link = Link->ForwardLink;
> > + }
> > +
> > + if (Link == &mGcdMemorySpaceMap) {
> > + return EFI_OUT_OF_RESOURCES;
> > + }
> > +
> > + //
> > + // Accept memory using the interface provide by the protocol.
> > + //
> > + Status = MemoryAcceptProtocol->AcceptMemory (MemoryAcceptProtocol, Start, AcceptSize);
> > + if (EFI_ERROR (Status)) {
> > + return EFI_OUT_OF_RESOURCES;
> > + }
> > +
> > + //
> > + // If memory is accepted successfully, remove the target memory space from GCD.
> > + //
> > + CoreRemoveMemorySpace (UnacceptedEntry.BaseAddress, UnacceptedEntry.EndAddress -
> UnacceptedEntry.BaseAddress + 1);
> > +
> > + //
> > + // Add the remain lower part of unaccepted memory to the
> > + // Gcd memory space and memory map.
> > + //
> > + if (Start > UnacceptedEntry.BaseAddress) {
> > + CoreAddMemorySpace (
> > + EFI_GCD_MEMORY_TYPE_UNACCEPTED,
> > + UnacceptedEntry.BaseAddress,
> > + Start - UnacceptedEntry.BaseAddress,
> > + UnacceptedEntry.Capabilities
> > + );
> > + }
> > +
> > + //
> > + // Update accepted part of the memory entry to type of EfiGcdMemoryTypeSystemMemory
> > + // and add the range to the memory map.
> > + //
> > + CoreAddMemorySpace (
> > + EfiGcdMemoryTypeSystemMemory,
> > + Start,
> > + AcceptSize,
> > + //
> > + // Hardcode memory space attributes.
> > + //
> > + EFI_MEMORY_CPU_CRYPTO | EFI_MEMORY_XP | EFI_MEMORY_RO | EFI_MEMORY_RP
> > + );
> > +
> > + //
> > + // Add the remain higher part of unaccepted memory to the
> > + // Gcd memory space and memory map.
> > + //
> > + if (UnacceptedEntry.EndAddress > End) {
> > + CoreAddMemorySpace (
> > + EFI_GCD_MEMORY_TYPE_UNACCEPTED,
> > + End + 1,
> > + UnacceptedEntry.EndAddress - End,
> > + UnacceptedEntry.Capabilities
> > + );
> > + }
> > +
> > + return EFI_SUCCESS;
> > +
> > + #else
> > +
> > + return EFI_UNSUPPORTED;
> > +
> > + #endif
> > +}
> > +
> > /**
> > Find untested but initialized memory regions in GCD map and convert them to be DXE allocatable.
> >
> > @@ -1486,6 +1657,25 @@ CoreAllocatePages (
> > Memory,
> > NeedGuard
> > );
> > + #ifdef MDE_CPU_X64
> > +
> > + if (Status == EFI_OUT_OF_RESOURCES) {
> > + Status = AcceptMemoryResource (Type, NumberOfPages << EFI_PAGE_SHIFT, Memory);
> > + if (!EFI_ERROR (Status)) {
> > + Status = CoreInternalAllocatePages (
> > + Type,
> > + MemoryType,
> > + NumberOfPages,
> > + Memory,
> > + NeedGuard
> > + );
> > + } else {
> > + Status = EFI_OUT_OF_RESOURCES;
> > + }
> > + }
> > +
> > + #endif
> > +
> > if (!EFI_ERROR (Status)) {
> > CoreUpdateProfile (
> > (EFI_PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
> > diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c
> > index 7aaf501600cf..9e8c8611c1ef 100644
> > --- a/MdeModulePkg/Core/Dxe/Mem/Pool.c
> > +++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c
> > @@ -273,6 +273,20 @@ CoreAllocatePool (
> > EFI_STATUS Status;
> >
> > Status = CoreInternalAllocatePool (PoolType, Size, Buffer);
> > +
> > + #ifdef MDE_CPU_X64
> > +
> > + if (Status == EFI_OUT_OF_RESOURCES) {
> > + Status = AcceptMemoryResource (AllocateAnyPages, Size, NULL);
> > + if (!EFI_ERROR (Status)) {
> > + Status = CoreInternalAllocatePool (PoolType, Size, Buffer);
> > + } else {
> > + Status = EFI_OUT_OF_RESOURCES;
> > + }
> > + }
> > +
> > + #endif
> > +
> > if (!EFI_ERROR (Status)) {
> > CoreUpdateProfile (
> > (EFI_PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
>
>
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#92939): https://edk2.groups.io/g/devel/message/92939
Mute This Topic: https://groups.io/mt/93285612/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
On August 30, 2022 8:29 AM, Ni, Ray wrote: > Can you please explain more about this patch? > I am a little nervous when seeing patches that change the fundamental > memory services. > With the introduction of lazy-page-accept, the OUT_OF_RESOURCE may occur in Memory Allocation logic (MdeModulePkg/Core/Dxe/Mem). To address this issue, this patch update the CoreAllocatePages()/CoreAllocatePool() so that when OUT_OF_RESOURCE is triggered, we can accept more unaccepted-memory with the help of EdkiiMemoryAcceptProtocol. Please refer to slide7-10 in https://edk2.groups.io/g/devel/files/Designs/2021/0830/ . It describes how the AcceptMemoryResource works. You can also refer to the discussion in https://edk2.groups.io/g/devel/message/79971. Thanks Min -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92958): https://edk2.groups.io/g/devel/message/92958 Mute This Topic: https://groups.io/mt/93285612/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
Min, My understanding is there is a TDX driver in DXE phase that accepts memory using MP protocol. We only need to make sure there is sufficient memory for code running before that point. Is my understanding correct? Thanks, Ray > -----Original Message----- > From: Xu, Min M <min.m.xu@intel.com> > Sent: Tuesday, August 30, 2022 2:01 PM > To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; > thomas.lendacky@amd.com > Cc: Gao, Jiaqi <jiaqi.gao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; > Gao, Liming <gaoliming@byosoft.com.cn>; Bi, Dandan > <dandan.bi@intel.com>; Aktas, Erdem <erdemaktas@google.com>; James > Bottomley <jejb@linux.ibm.com>; Yao, Jiewen <jiewen.yao@intel.com>; > Gerd Hoffmann <kraxel@redhat.com>; Xu, Min M <min.m.xu@intel.com> > Subject: RE: [edk2-devel] [PATCH V2 14/14] MdeModulePkg: Pool and page > functions accept memory when OOM occurs > > On August 30, 2022 8:29 AM, Ni, Ray wrote: > > Can you please explain more about this patch? > > I am a little nervous when seeing patches that change the fundamental > > memory services. > > > With the introduction of lazy-page-accept, the OUT_OF_RESOURCE may > occur in Memory Allocation logic (MdeModulePkg/Core/Dxe/Mem). To > address this issue, this patch update the > CoreAllocatePages()/CoreAllocatePool() so that when OUT_OF_RESOURCE is > triggered, we can accept more unaccepted-memory with the help of > EdkiiMemoryAcceptProtocol. > > Please refer to slide7-10 in > https://edk2.groups.io/g/devel/files/Designs/2021/0830/ . It describes how > the AcceptMemoryResource works. > > You can also refer to the discussion in > https://edk2.groups.io/g/devel/message/79971. > > Thanks > Min -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92959): https://edk2.groups.io/g/devel/message/92959 Mute This Topic: https://groups.io/mt/93285612/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
On August 30, 2022 2:15 PM, Ni Ray wrote: > Min, > My understanding is there is a TDX driver in DXE phase that accepts memory > using MP protocol. EdkiiMemoryAcceptProtocol is a protocol which accept memories. It is implemented/installed by the platform drivers, such as TdxDxe driver, or SEV driver. It is up to the platform driver (Tdx or SEV driver) if MP protocol is used. > We only need to make sure there is sufficient memory for code running > before that point. > Is my understanding correct? That's right. But we'd better accept sufficient memory for the whole DXE phase. If OOM is triggered it's better accept more memory than the size needed. In current implementation we accept the memory in units of 32MB. Thanks Min -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92961): https://edk2.groups.io/g/devel/message/92961 Mute This Topic: https://groups.io/mt/93285612/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
I saw the justification of this is to support different size of Linux kernel images. But that's after TD DXE driver. For code running before TD DXE driver, the memory needs is predicable, right? > -----Original Message----- > From: Xu, Min M <min.m.xu@intel.com> > Sent: Tuesday, August 30, 2022 2:35 PM > To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; > thomas.lendacky@amd.com > Cc: Gao, Jiaqi <jiaqi.gao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; > Gao, Liming <gaoliming@byosoft.com.cn>; Bi, Dandan > <dandan.bi@intel.com>; Aktas, Erdem <erdemaktas@google.com>; James > Bottomley <jejb@linux.ibm.com>; Yao, Jiewen <jiewen.yao@intel.com>; > Gerd Hoffmann <kraxel@redhat.com> > Subject: RE: [edk2-devel] [PATCH V2 14/14] MdeModulePkg: Pool and page > functions accept memory when OOM occurs > > On August 30, 2022 2:15 PM, Ni Ray wrote: > > Min, > > My understanding is there is a TDX driver in DXE phase that accepts > memory > > using MP protocol. > EdkiiMemoryAcceptProtocol is a protocol which accept memories. It is > implemented/installed by the platform drivers, such as TdxDxe driver, or SEV > driver. > It is up to the platform driver (Tdx or SEV driver) if MP protocol is used. > > We only need to make sure there is sufficient memory for code running > > before that point. > > Is my understanding correct? > That's right. But we'd better accept sufficient memory for the whole DXE > phase. If OOM is triggered it's better accept more memory than the size > needed. In current implementation we accept the memory in units of 32MB. > > Thanks > Min -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92962): https://edk2.groups.io/g/devel/message/92962 Mute This Topic: https://groups.io/mt/93285612/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
On August 30, 2022 3:12 PM, Ni Ray wrote: > > I saw the justification of this is to support different size of Linux kernel > images. > But that's after TD DXE driver. > For code running before TD DXE driver, the memory needs is predicable, > right? That's right. The memory before loading linux kernel is predicable. To support different size of linux kernel, there are hot discussions in EDK2/QEMU/LinuxKernel communities. There is a summary of the discussion in this link https://edk2.groups.io/g/devel/message/92332 I am also nervous to change in the fundamental memory allocation service (MdeModulePkg/Core/Dxe/Mem). Another option is that in current stage we accept memories under 4G and so that we can drop this patch (Pool and page functions accept memory when OOM occurs). What's your thoughts? Thanks Min -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92963): https://edk2.groups.io/g/devel/message/92963 Mute This Topic: https://groups.io/mt/93285612/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
> On August 30, 2022 3:12 PM, Ni Ray wrote: > > > > I saw the justification of this is to support different size of Linux kernel > > images. > > But that's after TD DXE driver. > > For code running before TD DXE driver, the memory needs is predicable, > > right? > That's right. The memory before loading linux kernel is predicable. > To support different size of linux kernel, there are hot discussions in > EDK2/QEMU/LinuxKernel communities. There is a summary of the discussion > in this link https://edk2.groups.io/g/devel/message/92332 > > I am also nervous to change in the fundamental memory allocation service > (MdeModulePkg/Core/Dxe/Mem). > Another option is that in current stage we accept memories under 4G and so > that we can drop this patch (Pool and page functions accept memory when > OOM occurs). > > What's your thoughts? Do you mean: Accepting 4G memory in ResetVector and accepting more memory in TD DXE driver through MP protocol? Does that need more time in ResetVector? If memory range to be accepted by ResetVector in a different meta data record than the memory ranges to be accepted by TD DXE driver? Thanks, Ray -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92964): https://edk2.groups.io/g/devel/message/92964 Mute This Topic: https://groups.io/mt/93285612/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
On August 30, 2022 3:44 PM, Ni Ray wrote: > > On August 30, 2022 3:12 PM, Ni Ray wrote: > > > > > > I saw the justification of this is to support different size of > > > Linux kernel images. > > > But that's after TD DXE driver. > > > For code running before TD DXE driver, the memory needs is > > > predicable, right? > > That's right. The memory before loading linux kernel is predicable. > > To support different size of linux kernel, there are hot discussions > > in EDK2/QEMU/LinuxKernel communities. There is a summary of the > > discussion in this link https://edk2.groups.io/g/devel/message/92332 > > > > I am also nervous to change in the fundamental memory allocation > > service (MdeModulePkg/Core/Dxe/Mem). > > Another option is that in current stage we accept memories under 4G > > and so that we can drop this patch (Pool and page functions accept > > memory when OOM occurs). > > > > What's your thoughts? > > Do you mean: > Accepting 4G memory in ResetVector and accepting more memory in TD DXE > driver through MP protocol? The unaccepted-memory-region is described in TdHob which is passed by QEMU. It includes the start address and size of the unaccepted-memory-region. Accepting memories under 4G is to accept the memories which start-address and size is under 4G. If an unaccept-memory-region is cross 4G, then it is split into 2 parts. We accept the lower part and leave the higher part as unaccepted. > > Does that need more time in ResetVector? TDVF accepts memories in SEC phase to make sure there are enough memories for PEI/DXE. Of course it costs more time to accept more memories. > Is memory range to be accepted by ResetVector in a different meta data > record than the memory ranges to be accepted by TD DXE driver? The unaccept-memory-region information is recorded first in TdHob (which is passed from QEMU). Before jumping to DXE phase the accepted and unaccepted memory region information are recorded in the HOBs which are transferred to DXE. In DXE these information will be recorded in mGcdMemorySpaceMap which will be used by the EdkiiMemoryAcceptProtocol. Thanks Min -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92966): https://edk2.groups.io/g/devel/message/92966 Mute This Topic: https://groups.io/mt/93285612/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
> > Do you mean: > > Accepting 4G memory in ResetVector and accepting more memory in TD > DXE > > driver through MP protocol? > The unaccepted-memory-region is described in TdHob which is passed by > QEMU. It includes the start address and size of the unaccepted-memory- > region. Accepting memories under 4G is to accept the memories which start- > address and size is under 4G. If an unaccept-memory-region is cross 4G, then > it is split into 2 parts. We accept the lower part and leave the higher part as > unaccepted. Then, how about you do a test boot to UEFI shell to collect the memory consumption then only accept that amount of memory in SEC? The amount of memory might cause SEC to accept memory above 4GB if the memory base is 3.99G already. -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92967): https://edk2.groups.io/g/devel/message/92967 Mute This Topic: https://groups.io/mt/93285612/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2026 Red Hat, Inc.