mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-20 20:24:28 +02:00
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:
parent
a63a7dbf85
commit
0596e5fa05
@ -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
|
||||
|
@ -95,6 +95,7 @@
|
||||
CpuExceptionHandlerLib
|
||||
PcdLib
|
||||
ImagePropertiesRecordLib
|
||||
OrderedCollectionLib
|
||||
|
||||
[Guids]
|
||||
gEfiEventMemoryMapChangeGuid ## PRODUCES ## Event
|
||||
|
@ -276,6 +276,12 @@ DxeMain (
|
||||
|
||||
MemoryProfileInit (HobStart);
|
||||
|
||||
//
|
||||
// Start the Handle Services.
|
||||
//
|
||||
Status = CoreInitializeHandleServices ();
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Start the Image Services.
|
||||
//
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user