From nobody Fri Nov 15 10:45:02 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90229+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90229+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1654484474; cv=none; d=zohomail.com; s=zohoarc; b=J2SOBxdeEA04X9jszHCKPLmqA0gogtMvZNyOLp+QKrcNVYwmrmAiLn3t6G5Xfo1HduDxbdRMX5w6zg4mYKBQRmOx+RS360t1eo2B9jGNsJA3/Zx2xKzbgr5muw4wKtGQaeLKa9/QAHOZG2idq+splVA4iTJzXnX58Yv9gmALfg4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1654484474; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=dRXOICl2Hi7XjzsdJGihsByHE3xHSeguoUO7iEpK1Ug=; b=WgPZOa0P6PYGtO745v0iYtbiSN3y2zK9u2uDTKWX7m2RzSZ094llf5Qv/UhF6UDncg+8IGD9/R/ozLT4L+b9onLRkuw3LzWwjB5AlOmgLrMZoSiUUA0vaAUFIPDo3VL3ConUIb5dU6dL2IBxWvgjEmAPi4pxijXwEAt8ZD9xGBM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90229+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1654484474354412.91841478093806; Sun, 5 Jun 2022 20:01:14 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id CDXOYY1788612xDcOmPWNVns; Sun, 05 Jun 2022 20:01:14 -0700 X-Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web12.27724.1654484472793901780 for ; Sun, 05 Jun 2022 20:01:13 -0700 X-IronPort-AV: E=McAfee;i="6400,9594,10369"; a="276458198" X-IronPort-AV: E=Sophos;i="5.91,280,1647327600"; d="scan'208";a="276458198" X-Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jun 2022 20:00:53 -0700 X-IronPort-AV: E=Sophos;i="5.91,280,1647327600"; d="scan'208";a="647285867" X-Received: from mxu9-mobl1.ccr.corp.intel.com ([10.255.29.66]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jun 2022 20:00:50 -0700 From: "Min Xu" To: devel@edk2.groups.io Cc: Jiaqi Gao , Jian J Wang , Liming Gao , Dandan Bi , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky , Gerd Hoffmann , Min Xu Subject: [edk2-devel] [PATCH 14/14] MdeModulePkg: Pool and page functions accept memory when OOM occurs Date: Mon, 6 Jun 2022 11:00:02 +0800 Message-Id: <0c6aadb4fbf75d804a491e871b250cd5d39a1589.1654420876.git.min.m.xu@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: PQSQ723v3Jwe2zr8KQdsSbfjx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1654484474; bh=iNrFfEn1A8hjyI9VisjatpzMg16Psw7z3vhs/j9ju50=; h=Cc:Date:From:Reply-To:Subject:To; b=aXV6BbFWU1UDgZrOVZt9Khs8vftMAZRK2crclEWpnNjBHIwtqYbZu50D+TyzfFuMuaL KZQ8PJzOz37BJFJENxLd2So4T4TKTLMyKMmwurZsYKXpDaMTot/mMqyUrrZONqwXOK4xb Hst4GIKxxR9Oyv5CF2EmgAlZeblhhlS4ODY= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1654484475069100012 Content-Type: text/plain; charset="utf-8" From: Jiaqi Gao RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3937 When CoreAllocatePages()/CoreAllocatePool() meets error of EFI_OUT_OF_RESOURCES, locate the EfiMemoryAcceptProtocol and accept extra memory dynamically. Firstly, find the unaccpeted memory region with enough size in GCD entries. Then locate the EfiMemoryAcceptProtocol 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 Cc: Liming Gao Cc: Dandan Bi Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Cc: Gerd Hoffmann Signed-off-by: Jiaqi Gao Signed-off-by: Min Xu --- 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/DxeM= ain.inf index e4bca895773d..4b6c627a2cde 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -169,6 +169,7 @@ gEfiVariableArchProtocolGuid ## CONSUMES gEfiCapsuleArchProtocolGuid ## CONSUMES gEfiWatchdogTimerArchProtocolGuid ## CONSUMES + gEfiMemoryAcceptProtocolGuid ## CONSUMES =20 [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber = ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Core/Dxe/Mem/Imem.h b/MdeModulePkg/Core/Dxe/Mem/I= mem.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 // =20 +/** + 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/P= age.c index 008efdf397e0..0584373d68be 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -9,6 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "DxeMain.h" #include "Imem.h" #include "HeapGuard.h" +#include =20 // // Entry for tracking the memory regions for each memory type to coalesce = similar memory types @@ -378,6 +379,176 @@ CoreFreeMemoryMapStack ( mFreeMapStack -=3D 1; } =20 +/** + 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; + EFI_MEMORY_ACCEPT_PROTOCOL *MemoryAcceptProtocol; + UINTN Start; + UINTN End; + EFI_STATUS Status; + + // + // We accept n*32MB at one time to improve the efficiency. + // + AcceptSize =3D (AcceptSize + SIZE_32MB - 1) & ~(SIZE_32MB - 1); + + if (AcceptSize =3D=3D 0) { + return EFI_INVALID_PARAMETER; + } + + Status =3D gBS->LocateProtocol (&gEfiMemoryAcceptProtocolGuid, NULL, (VO= ID **)&MemoryAcceptProtocol); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + if (Type =3D=3D AllocateAddress) { + Start =3D *Memory; + End =3D *Memory + AcceptSize; + } + + if (Type =3D=3D AllocateMaxAddress) { + if (*Memory < EFI_PAGE_MASK) { + return EFI_INVALID_PARAMETER; + } + + if ((*Memory & EFI_PAGE_MASK) !=3D EFI_PAGE_MASK) { + // + // Change MaxAddress to be 1 page lower + // + *Memory -=3D EFI_PAGE_SIZE; + + // + // Set MaxAddress to a page boundary + // + *Memory &=3D ~(UINT64)EFI_PAGE_MASK; + + // + // Set MaxAddress to end of the page + // + *Memory |=3D EFI_PAGE_MASK; + } + } + + // + // Traverse the mGcdMemorySpaceMap to find out the unaccepted + // memory entry with big enough size. + // + Link =3D mGcdMemorySpaceMap.ForwardLink; + while (Link !=3D &mGcdMemorySpaceMap) { + GcdEntry =3D CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); + if (GcdEntry->GcdMemoryType =3D=3D EfiGcdMemoryTypeUnaccepted) { + if (Type =3D=3D AllocateMaxAddress) { + if (GcdEntry->BaseAddress + AcceptSize - 1 > *Memory) { + Link =3D Link->ForwardLink; + continue; + } + } else if (Type =3D=3D AllocateAddress) { + if ((GcdEntry->BaseAddress > *Memory) || (GcdEntry->EndAddress < *= Memory + AcceptSize - 1)) { + Link =3D Link->ForwardLink; + continue; + } + } + + // + // Is the entry big enough? + // + if (AcceptSize <=3D GcdEntry->EndAddress - GcdEntry->BaseAddress + 1= ) { + UnacceptedEntry =3D *GcdEntry; + if (Type !=3D AllocateAddress) { + Start =3D UnacceptedEntry.BaseAddress; + End =3D UnacceptedEntry.BaseAddress + AcceptSize - 1; + } + + break; + } + } + + Link =3D Link->ForwardLink; + } + + if (Link =3D=3D &mGcdMemorySpaceMap) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Accept memory using the interface provide by the protocol. + // + Status =3D MemoryAcceptProtocol->AcceptMemory (MemoryAcceptProtocol, Sta= rt, AcceptSize); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + // + // If memory is accepted successfully, remove the target memory space fr= om GCD. + // + CoreRemoveMemorySpace (UnacceptedEntry.BaseAddress, UnacceptedEntry.EndA= ddress - UnacceptedEntry.BaseAddress + 1); + + // + // Add the remain lower part of unaccepted memory to the + // Gcd memory space and memory map. + // + if (Start > UnacceptedEntry.BaseAddress) { + CoreAddMemorySpace ( + EfiGcdMemoryTypeUnaccepted, + UnacceptedEntry.BaseAddress, + Start - UnacceptedEntry.BaseAddress, + UnacceptedEntry.Capabilities + ); + } + + // + // Update accepted part of the memory entry to type of EfiGcdMemoryTypeS= ystemMemory + // 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 ( + EfiGcdMemoryTypeUnaccepted, + 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. =20 @@ -1471,6 +1642,25 @@ CoreAllocatePages ( Memory, NeedGuard ); + #ifdef MDE_CPU_X64 + + if (Status =3D=3D EFI_OUT_OF_RESOURCES) { + Status =3D AcceptMemoryResource (Type, NumberOfPages << EFI_PAGE_SHIFT= , Memory); + if (!EFI_ERROR (Status)) { + Status =3D CoreInternalAllocatePages ( + Type, + MemoryType, + NumberOfPages, + Memory, + NeedGuard + ); + } else { + Status =3D 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/P= ool.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; =20 Status =3D CoreInternalAllocatePool (PoolType, Size, Buffer); + + #ifdef MDE_CPU_X64 + + if (Status =3D=3D EFI_OUT_OF_RESOURCES) { + Status =3D AcceptMemoryResource (AllocateAnyPages, Size, NULL); + if (!EFI_ERROR (Status)) { + Status =3D CoreInternalAllocatePool (PoolType, Size, Buffer); + } else { + Status =3D EFI_OUT_OF_RESOURCES; + } + } + + #endif + if (!EFI_ERROR (Status)) { CoreUpdateProfile ( (EFI_PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90229): https://edk2.groups.io/g/devel/message/90229 Mute This Topic: https://groups.io/mt/91570214/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-