[edk2-devel] purpose of EFI_LOCK

Laszlo Ersek lersek at redhat.com
Thu May 4 08:45:00 UTC 2023


Hi,

what benefit does EFI_LOCK add, over direct gBS->RaiseTPL() and
gBS->RestoreTPL() calls?

Considering just the two APIs EfiAcquireLock() and EfiReleaseLock():

- The "Lock" field (effectively, lock status field) is useless; it is
only written to, never read (outside of ASSERT()s)

- The "OwnerTpl" and "Tpl" fields are just convenience storage for the
new TPL we raise to, and the old TPL we restore.

Considering the EfiAcquireLockOrFail() API as well:

- This does read the "Lock" (lock status) field, and if it is
EfiLockAcquired, the RaiseTPL() call is refused. So the idea here seems
to be to ensure a *strict* rise in the TPL. Namely, the RaiseTPL() in
EfiAcquireLockOrFail() would still succeed after the RaiseTPL() in
EfiAcquireLock() -- it is valid to "raise" the TPL to the current TPL
--, but the lock status check prevents that.

- However (#1), this same "strict" raise would be possible by just
calling RaiseTPL() again, and comparing the returned old TPL against the
TPL we've just set as new. If the old TPL is strictly lower, then we've
just "acquired the lock", otherwise we've "already been holding" the
lock. So, from this perspective, EfiAcquireLockOrFail() doesn't add much.

- Furthermore (#2), if another agent raised the TPL already, but didn't
use our particlar EFI_LOCK object to do that, then the status stored in
"EFI_LOCK.Lock" will not be able to track anything.

So what is EFI_LOCK good for?

Effectively I'm disturbed by the *name* "EFI_LOCK". A lock (or mutex) is
supposed to protect some shared resource. If two agents access the
resource without first acquiring the lock, there's trouble. Therefore
the resource itself becomes qualified as "requiring protection by the
lock, at all times". However, the "current TPL" is *not* a resource like
that. It's a UEFI spec level concept; the RaiseTPL and RestoreTPL boot
services are available to any agents; those agents are *not* required to
go through any kind of extra mutual exclusion.

I've also considered that maybe EFI_LOCK could provide some protection
against inadvertently *lowering* the TPL via RaiseTPL() (which is
undefined behavior, per spec). But I don't see how --
EfiAcquireLockOrFail() will happily lower the TPL if the Lock field is
EfiLockReleased, but another agent has meanwhile raised the TPL strictly
above the Tpl field.

Please explain. :)

Thanks!
Laszlo



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#103980): https://edk2.groups.io/g/devel/message/103980
Mute This Topic: https://groups.io/mt/98680041/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/leave/3943202/1813853/130120423/xyzzy [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list