[RFC PATCH 0/2] Clean up protocol installation API
Heinrich Schuchardt
xypron.glpk at gmx.de
Thu Oct 6 11:54:13 CEST 2022
On 10/6/22 08:55, Ilias Apalodimas wrote:
> Hi Akashi-san,
>
> On Thu, 6 Oct 2022 at 04:35, AKASHI Takahiro <takahiro.akashi at linaro.org> wrote:
>>
>> Hi Ilias,
>>
>> On Wed, Oct 05, 2022 at 06:26:00PM +0300, Ilias Apalodimas wrote:
>>> This RFC is trying to clean up the usage of the internal functions used
>>> to manage the protocol and handle lifetimes. Currently we arbitrarily
>>> use either InstallProtocol, InstallMultipleProtocol and a combination of
>>> efi_add_protocol, efi_create_handle, efi_delete_handle(). The latter
>>> is the most problematic one since it blindly removes all protocols from
>>> a handle and finally the handle itself. This is prone to coding errors
>>> Since someone might inadvertently delete a handle while other consumers
>>> still use a protocol.
The logic for keeping protocol interfaces depends on the open protocol
information records. UninstallProtocolInterface() takes these into account:
If a protocol interface is opened with BY_DRIVER or BY_CHILD_CONTROLLER,
DisconnectController() is called. For all remaining open protocol
information records CloseProtocol() is called.
Best regards
Heinrich
>>
>> I'm not sure about what specific issue you're trying to fix with this patch.
>> Looking at patch#2, you simply replace efi_delete_handle() with
>> uninstall_multiple_protocol_interfaces(). So the problem still stay there
>> because it seems that we still have to care about where and when those
>> functions should be called any way.
>
> No that's handled automatically in
> uninstall_multiple_protocol_interfaces(). Imagine 2 different
> functions installing protocols on the same handle. With the current
> code if one calls efi_delete_handle() it will delete all the protocols
> and the handle, while uninstall_multiple_protocol_interfaces() will
> preserve the protocols it has to. Arguably calling
> efi_delete_handle() in that case is a coding error, but in any case
> we should provide users with an API that shields them against mistakes
> like that.
>
>>
>> That said, I don't think your cleanup is meaningless; there is a difference
>> between efi_delete_handle() and efi_uninstall_multiple_protocol_interfaces().
>> The former calls efi_remove_protocol() internally, whereas the latter calls
>> efi_uninstall_protocol(); That makes difference.
>>
>> In the description of UninstallProtocolInterface in UEFI spec,
>> "The caller is responsible for ensuring that there are no references
>> to a protocol interface that has been removed. In some cases, outstanding
>> reference information is not available in the protocol, so the protocol,
>> once added, cannot be removed."
>> "EFI 1.10 Extension
>>
>> The extension to this service directly addresses the limitations described in
>> the section above. There may be some drivers that are currently consuming
>> the protocol interface that needs to be uninstalled, so it may be dangerous
>> to just blindly remove a protocol interface from the system. Since the usage
>> of protocol interfaces is now being tracked for components that use
>> the EFI_BOOT_SERVICES.OpenProtocol() and EFI_BOOT_SERVICES.CloseProtocol()."
>>
>> So I think you can rationalize your clean-up more specifically.
>
> Those are 2 different problems but I'll add the description for open
> protocols as well.
>
>>
>> Here, I have a concern. According to UEFI spec above, I've got an impression
>> that UninstalllProtocolInterface() should fails if someone still opens
>> a protocol associated with a handle as UEFI subsystem is set to maintain such
>> "open" information in handle database.
>> There is some logic there regarding EFI_OPEN_PROTOCOL_xxx, but I'm not sure
>> it works as expected under the current implementation.
>> I think that this issue is to be addressed, or at least investigated.
>>
>> -Takahiro Akashi
>
> Thanks
> /Ilias
>
>>
>>> InstallProtocol is also ambiguous since the EFI spec only demands
>>> InstallMultipleProtocol to test and guarantee a duplicate device path is
>>> not inadvertently installed on two different handles. So this patch
>>> series is preparing the ground in order for InstallMultipleProtocol and
>>> UnInstallMultipleProtocol to be used internally in U-Boot.
>>>
>>> There is an example on bootefi.c demonstrating how the cleanup would
>>> eventually look like. If we agree on the direction, I'll clean up the
>>> remaining callsites with InstallMultipleProtocol.
>>>
>>> Size differences between old/new binary show that eventually we will
>>> manage to reduce the overall code size by getting rid all the
>>> unneeded EFI_CALL invocations
>>>
>>> add/remove: 4/0 grow/shrink: 1/6 up/down: 1128/-892 (236)
>>> Function old new delta
>>> __efi_install_multiple_protocol_interfaces - 496 +496
>>> __efi_uninstall_multiple_protocol_interfaces - 412 +412
>>> efi_uninstall_multiple_protocol_interfaces_ext - 108 +108
>>> efi_install_multiple_protocol_interfaces_ext - 108 +108
>>> efi_run_image 288 292 +4
>>> efi_initrd_register 220 212 -8
>>> efi_console_register 344 336 -8
>>> efi_disk_add_dev.part 644 632 -12
>>> efi_root_node_register 256 240 -16
>>> efi_uninstall_multiple_protocol_interfaces 472 84 -388
>>> efi_install_multiple_protocol_interfaces 544 84 -460
>>> Total: Before=547442, After=547678, chg +0.04%
>>> add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0 (0)
>>> Data old new delta
>>> Total: Before=101061, After=101061, chg +0.00%
>>> add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0 (0)
>>> RO Data old new delta
>>> Total: Before=42925, After=42925, chg +0.00%
>>>
>>> Ilias Apalodimas (2):
>>> efi_loader: define internal implementation of
>>> install/uninstallmultiple
>>> cmd: replace efi_create_handle/add_protocol with
>>> InstallMultipleProtocol
>>>
>>> cmd/bootefi.c | 13 ++-
>>> include/efi.h | 2 +
>>> include/efi_loader.h | 6 +-
>>> lib/efi_loader/efi_boottime.c | 180 ++++++++++++++++++++++++-------
>>> lib/efi_loader/efi_capsule.c | 15 +--
>>> lib/efi_loader/efi_console.c | 14 +--
>>> lib/efi_loader/efi_disk.c | 10 +-
>>> lib/efi_loader/efi_load_initrd.c | 15 ++-
>>> lib/efi_loader/efi_root_node.c | 44 ++++----
>>> 9 files changed, 203 insertions(+), 96 deletions(-)
>>>
>>> --
>>> 2.34.1
>>>
More information about the U-Boot
mailing list