MdeModulePkg: CoreValidateHandle Optimization

REF : https://bugzilla.tianocore.org/show_bug.cgi?id=4817

Before entering BIOS setup, CoreValidateHandle function executed
over 600,000 times during BDS phase on latest 8S server platform.
In CoreValidateHandle function, current implementation will go
through the doubly-linked list handle database in each call, and
this will have big impact on boot performance.
The optimization is using Red-black tree to store the EFI handle
address when insert each EFI handle into the handle database, and
remove the handle from Red-black tree if the handle is removed
from the handle database. CoreValidateHandle function changed to
go through the Red-black tree.
After verification on latest 8S server platform, BDS boot time can
save 20s+ after this change.

Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Andrew Fish <afish@apple.com>
Tested-by: Xiaoqiang Zhang <xiaoqiang.zhang@intel.com>
This commit is contained in:
Xiaoqiang Zhang 2024-08-07 16:42:44 +08:00 committed by mergify[bot]
parent a63a7dbf85
commit 0596e5fa05
4 changed files with 97 additions and 11 deletions

View File

@ -84,6 +84,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/DxeServicesLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/CpuExceptionHandlerLib.h>
#include <Library/OrderedCollectionLib.h>
//
// attributes for reserved memory before it is promoted to system memory
@ -2790,4 +2791,15 @@ MergeMemoryMap (
IN UINTN DescriptorSize
);
/**
Initializes "handle" support.
@return Status code.
+**/
EFI_STATUS
CoreInitializeHandleServices (
VOID
);
#endif

View File

@ -95,6 +95,7 @@
CpuExceptionHandlerLib
PcdLib
ImagePropertiesRecordLib
OrderedCollectionLib
[Guids]
gEfiEventMemoryMapChangeGuid ## PRODUCES ## Event

View File

@ -276,6 +276,12 @@ DxeMain (
MemoryProfileInit (HobStart);
//
// Start the Handle Services.
//
Status = CoreInitializeHandleServices ();
ASSERT_EFI_ERROR (Status);
//
// Start the Image Services.
//

View File

@ -19,6 +19,7 @@ LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolData
LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
UINT64 gHandleDatabaseKey = 0;
ORDERED_COLLECTION *gOrderedHandleList = NULL;
/**
Acquire lock on gProtocolDatabaseLock.
@ -44,6 +45,60 @@ CoreReleaseProtocolLock (
CoreReleaseLock (&gProtocolDatabaseLock);
}
/**
Comparator function for two opaque pointers, ordering on (unsigned) pointer
value itself.
Can be used as both Key and UserStruct comparator.
@param[in] Pointer1 First pointer.
@param[in] Pointer2 Second pointer.
@retval <0 If Pointer1 compares less than Pointer2.
@retval 0 If Pointer1 compares equal to Pointer2.
@retval >0 If Pointer1 compares greater than Pointer2.
**/
STATIC
INTN
EFIAPI
PointerCompare (
IN CONST VOID *Pointer1,
IN CONST VOID *Pointer2
)
{
if (Pointer1 == Pointer2) {
return 0;
}
if ((UINTN)Pointer1 < (UINTN)Pointer2) {
return -1;
}
return 1;
}
/**
Initializes "handle" support.
@return Status code.
**/
EFI_STATUS
CoreInitializeHandleServices (
VOID
)
{
gOrderedHandleList = OrderedCollectionInit (PointerCompare, PointerCompare);
if (gOrderedHandleList == NULL) {
return EFI_OUT_OF_RESOURCES;
}
return EFI_SUCCESS;
}
/**
Check whether a handle is a valid EFI_HANDLE
The gProtocolDatabaseLock must be owned
@ -59,8 +114,7 @@ CoreValidateHandle (
IN EFI_HANDLE UserHandle
)
{
IHANDLE *Handle;
LIST_ENTRY *Link;
ORDERED_COLLECTION_ENTRY *Entry;
if (UserHandle == NULL) {
return EFI_INVALID_PARAMETER;
@ -68,12 +122,10 @@ CoreValidateHandle (
ASSERT_LOCKED (&gProtocolDatabaseLock);
for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) {
Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
if (Handle == (IHANDLE *)UserHandle) {
Entry = OrderedCollectionFind (gOrderedHandleList, UserHandle);
if (Entry != NULL) {
return EFI_SUCCESS;
}
}
return EFI_INVALID_PARAMETER;
}
@ -452,6 +504,16 @@ CoreInstallProtocolInterfaceNotify (
goto Done;
}
//
// Add this handle to the ordered list of all handles
// in the system
//
Status = OrderedCollectionInsert (gOrderedHandleList, NULL, Handle);
if (EFI_ERROR (Status)) {
CoreFreePool (Handle);
goto Done;
}
//
// Initialize new handler structure
//
@ -825,6 +887,11 @@ CoreUninstallProtocolInterface (
//
if (IsListEmpty (&Handle->Protocols)) {
Handle->Signature = 0;
OrderedCollectionDelete (
gOrderedHandleList,
OrderedCollectionFind (gOrderedHandleList, Handle),
NULL
);
RemoveEntryList (&Handle->AllHandles);
CoreFreePool (Handle);
}