mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-21 04:34:27 +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/DxeServicesLib.h>
|
||||||
#include <Library/DebugAgentLib.h>
|
#include <Library/DebugAgentLib.h>
|
||||||
#include <Library/CpuExceptionHandlerLib.h>
|
#include <Library/CpuExceptionHandlerLib.h>
|
||||||
|
#include <Library/OrderedCollectionLib.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// attributes for reserved memory before it is promoted to system memory
|
// attributes for reserved memory before it is promoted to system memory
|
||||||
@ -2790,4 +2791,15 @@ MergeMemoryMap (
|
|||||||
IN UINTN DescriptorSize
|
IN UINTN DescriptorSize
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes "handle" support.
|
||||||
|
|
||||||
|
@return Status code.
|
||||||
|
|
||||||
|
+**/
|
||||||
|
EFI_STATUS
|
||||||
|
CoreInitializeHandleServices (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -95,6 +95,7 @@
|
|||||||
CpuExceptionHandlerLib
|
CpuExceptionHandlerLib
|
||||||
PcdLib
|
PcdLib
|
||||||
ImagePropertiesRecordLib
|
ImagePropertiesRecordLib
|
||||||
|
OrderedCollectionLib
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiEventMemoryMapChangeGuid ## PRODUCES ## Event
|
gEfiEventMemoryMapChangeGuid ## PRODUCES ## Event
|
||||||
|
@ -276,6 +276,12 @@ DxeMain (
|
|||||||
|
|
||||||
MemoryProfileInit (HobStart);
|
MemoryProfileInit (HobStart);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start the Handle Services.
|
||||||
|
//
|
||||||
|
Status = CoreInitializeHandleServices ();
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Start the Image Services.
|
// Start the Image Services.
|
||||||
//
|
//
|
||||||
|
@ -15,10 +15,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
// gProtocolDatabaseLock - Lock to protect the mProtocolDatabase
|
// gProtocolDatabaseLock - Lock to protect the mProtocolDatabase
|
||||||
// gHandleDatabaseKey - The Key to show that the handle has been created/modified
|
// gHandleDatabaseKey - The Key to show that the handle has been created/modified
|
||||||
//
|
//
|
||||||
LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);
|
LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);
|
||||||
LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
|
LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
|
||||||
EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
|
EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
|
||||||
UINT64 gHandleDatabaseKey = 0;
|
UINT64 gHandleDatabaseKey = 0;
|
||||||
|
ORDERED_COLLECTION *gOrderedHandleList = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Acquire lock on gProtocolDatabaseLock.
|
Acquire lock on gProtocolDatabaseLock.
|
||||||
@ -44,6 +45,60 @@ CoreReleaseProtocolLock (
|
|||||||
CoreReleaseLock (&gProtocolDatabaseLock);
|
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
|
Check whether a handle is a valid EFI_HANDLE
|
||||||
The gProtocolDatabaseLock must be owned
|
The gProtocolDatabaseLock must be owned
|
||||||
@ -59,8 +114,7 @@ CoreValidateHandle (
|
|||||||
IN EFI_HANDLE UserHandle
|
IN EFI_HANDLE UserHandle
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IHANDLE *Handle;
|
ORDERED_COLLECTION_ENTRY *Entry;
|
||||||
LIST_ENTRY *Link;
|
|
||||||
|
|
||||||
if (UserHandle == NULL) {
|
if (UserHandle == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
@ -68,11 +122,9 @@ CoreValidateHandle (
|
|||||||
|
|
||||||
ASSERT_LOCKED (&gProtocolDatabaseLock);
|
ASSERT_LOCKED (&gProtocolDatabaseLock);
|
||||||
|
|
||||||
for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) {
|
Entry = OrderedCollectionFind (gOrderedHandleList, UserHandle);
|
||||||
Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
|
if (Entry != NULL) {
|
||||||
if (Handle == (IHANDLE *)UserHandle) {
|
return EFI_SUCCESS;
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
@ -452,6 +504,16 @@ CoreInstallProtocolInterfaceNotify (
|
|||||||
goto Done;
|
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
|
// Initialize new handler structure
|
||||||
//
|
//
|
||||||
@ -825,6 +887,11 @@ CoreUninstallProtocolInterface (
|
|||||||
//
|
//
|
||||||
if (IsListEmpty (&Handle->Protocols)) {
|
if (IsListEmpty (&Handle->Protocols)) {
|
||||||
Handle->Signature = 0;
|
Handle->Signature = 0;
|
||||||
|
OrderedCollectionDelete (
|
||||||
|
gOrderedHandleList,
|
||||||
|
OrderedCollectionFind (gOrderedHandleList, Handle),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
RemoveEntryList (&Handle->AllHandles);
|
RemoveEntryList (&Handle->AllHandles);
|
||||||
CoreFreePool (Handle);
|
CoreFreePool (Handle);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user