EFI Group Event Callback Order
Li, Walon <walon.li@...>
Hi edk2,
As UEFI event group mechanism, we can register callbacks under event group. For example, register two event callbacks and will be signal in ReadyToBoot. Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, TestCallback1, NULL, &gEfiEventReadyToBootGuid, &ReadyToBootEvent ); Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, TestCallback2, NULL, &gEfiEventReadyToBootGuid, &ReadyToBootEvent ); I'm curious the order of callback. In this case, the order is LIFO and TestCallback2 will be executed than TestCallback1. As the UEFI spec page 152, only said "If the supplied Event is a part of an event group, then all of the events in the event group are also signaled and their notification functions are scheduled." It doesn't define order clearly.
However, edk2 has different implementation in EVT_RUNTIME / EVT_NOTIFY_SIGNAL attribute of group event. In Event.c, it inserts new event to Head in EVT_NOTIFY_SIGNAL queue (LIFO) and inserts to Tail in EVT_RUNTIME queue (FIFO). I know the programmer shouldn't assume any order but want to know why is different implementation in group event. Have any history reason or limitation?
if ((Type & EVT_RUNTIME) != 0) { // // Keep a list of all RT events so we can tell the RT AP. // IEvent->RuntimeData.Type = Type; IEvent->RuntimeData.NotifyTpl = NotifyTpl; IEvent->RuntimeData.NotifyFunction = NotifyFunction; IEvent->RuntimeData.NotifyContext = (VOID *) NotifyContext; // // Work around the bug in the Platform Init specification (v1.7), reported // as Mantis#2017: "EFI_RUNTIME_EVENT_ENTRY.Event" should have type // EFI_EVENT, not (EFI_EVENT*). The PI spec documents the field correctly // as "The EFI_EVENT returned by CreateEvent()", but the type of the field // doesn't match the natural language description. Therefore we need an // explicit cast here. // IEvent->RuntimeData.Event = (EFI_EVENT *) IEvent; InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link); }
CoreAcquireEventLock ();
if ((Type & EVT_NOTIFY_SIGNAL) != 0x00000000) { // // The Event's NotifyFunction must be queued whenever the event is signaled // InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink); }
Thank you, Walon
|
|
Laszlo Ersek
On 01/16/20 09:32, Li, Walon wrote:
Hi edk2,It's unspecified. Implementations may differ, and an implementation isn't even required to be self-consistent wrt. the order. Ordering is only specified in terms of TPLs. Thanks Laszlo
|
|
Li, Walon
Laszlo,
toggle quoted messageShow quoted text
Yes, we can specific TPL to adjust callback order. But sometimes, an event has many callbacks like as ReadyToBoot and TPL level may not satisfy purpose. In UEFI spec CreateEvent chapter, also mentioned "The functions in these queues are invoked in FIFO order". So, if it define clearly in UEFI spec, LIFO or FIFO, we may use driver dependency to decide which driver's event registration priority and specific callback order indirectly. Thank you, Walon
-----Original Message-----
From: Laszlo Ersek [mailto:lersek@...] Sent: Friday, January 17, 2020 4:09 PM To: discuss@edk2.groups.io; Li, Walon <walon.li@...> Subject: Re: [edk2-discuss] EFI Group Event Callback Order On 01/16/20 09:32, Li, Walon wrote: Hi edk2, It's unspecified. Implementations may differ, and an implementation isn't even required to be self-consistent wrt. the order. Ordering is only specified in terms of TPLs. Thanks Laszlo
|
|
Tomas Pilar (tpilar)
I had to solve this for myself by creating a PostReadyToBoot event that is signalled by my ReadyToBoot callback. That meant that my PostReadyToBoot callbacks got executed after all the ReadyToBoot event functions.
Cheers, Tom ________________________________________ From: discuss@edk2.groups.io <discuss@edk2.groups.io> on behalf of Li, Walon <walon.li@...> Sent: 17 January 2020 13:24 To: discuss@edk2.groups.io; Laszlo Ersek Cc: Wei, Kent (HPS SW); Wang, Sunny (HPS SW); Chang, Abner (HPS SW/FW Technologist); Spottswood, Jason; Shifflett, Joseph; Haskell, Darrell; Wiginton, Scott Subject: Re: [edk2-discuss] EFI Group Event Callback Order Laszlo, Yes, we can specific TPL to adjust callback order. But sometimes, an event has many callbacks like as ReadyToBoot and TPL level may not satisfy purpose. In UEFI spec CreateEvent chapter, also mentioned "The functions in these queues are invoked in FIFO order". So, if it define clearly in UEFI spec, LIFO or FIFO, we may use driver dependency to decide which driver's event registration priority and specific callback order indirectly. Thank you, Walon -----Original Message----- From: Laszlo Ersek [mailto:lersek@...] Sent: Friday, January 17, 2020 4:09 PM To: discuss@edk2.groups.io; Li, Walon <walon.li@...> Subject: Re: [edk2-discuss] EFI Group Event Callback Order On 01/16/20 09:32, Li, Walon wrote: Hi edk2, It's unspecified. Implementations may differ, and an implementation isn't even required to be self-consistent wrt. the order. Ordering is only specified in terms of TPLs. Thanks Laszlo The information contained in this message is confidential and is intended for the addressee(s) only. If you have received this message in error, please notify the sender immediately and delete the message. Unless you are an addressee (or authorized to receive for an addressee), you may not use, copy or disclose to anyone this message or any information contained in this message. The unauthorized use, disclosure, copying or alteration of this message is strictly prohibited.
|
|
Laszlo Ersek
On 01/17/20 14:24, Li, Walon wrote:
Laszlo,The FIFO order refers to something else. Here's a larger citation: When the event is signaled, firmware changes its state to “signaled” and, if EVT_NOTIFY_SIGNAL is specified, places a call to its notification function in a FIFO queue. There is a queue for each of the “basic” task priority levels defined in Section 7.1 (TPL_CALLBACK, and TPL_NOTIFY). The functions in these queues are invoked in FIFO order, starting with the highest priority level queue and proceeding to the lowest priority queue that is unmasked by the current TPL. It means that, within a given TPL, the notification function invocation order will reflect the enqueueing (= signaling) order. But the spec does not specify the *signaling* order for such events that belong to the same event group, when one of those events is signaled. The spec says, Event groups are collections of events identified by a shared EFI_GUID where, when one member event is signaled, all other events are signaled and their individual notification actions are taken (as described in CreateEvent). All events are guaranteed to be signaled before the first notification action is taken. All notification functions will be executed in the order specified by their NotifyTpl. So if you have two events, A and B, and they belong to the same event group G, and NotifyTpl is the same for both, then if you signal either A or B, then the notification functions may be queued, *and invoked*, in either (A, B), or (B, A), order. The invocation order will reflect the queueing order, yes, but the latter is unspecified, when you go through an event group. Thanks Laszlo
|
|
Li, Walon
Thanks for your explanation, it's very clear.
toggle quoted messageShow quoted text
Is it possible to update spec that makes unspecified behavior to specified? I know the implementation is in accordance with spec but add some comments can make programmer use this mechanism flexible. Thanks! Walon
-----Original Message-----
From: Laszlo Ersek [mailto:lersek@...] Sent: Saturday, January 18, 2020 2:19 AM To: Li, Walon <walon.li@...>; discuss@edk2.groups.io Cc: Wei, Kent (HPS SW) <kent.wei@...>; Wang, Sunny (HPS SW) <sunnywang@...>; Chang, Abner (HPS SW/FW Technologist) <abner.chang@...>; Spottswood, Jason <jason.spottswood@...>; Shifflett, Joseph <joseph.shifflett@...>; Haskell, Darrell <darrell.haskell@...>; Wiginton, Scott <scott.wiginton@...> Subject: Re: [edk2-discuss] EFI Group Event Callback Order On 01/17/20 14:24, Li, Walon wrote: Laszlo,The FIFO order refers to something else. Here's a larger citation: When the event is signaled, firmware changes its state to "signaled" and, if EVT_NOTIFY_SIGNAL is specified, places a call to its notification function in a FIFO queue. There is a queue for each of the "basic" task priority levels defined in Section 7.1 (TPL_CALLBACK, and TPL_NOTIFY). The functions in these queues are invoked in FIFO order, starting with the highest priority level queue and proceeding to the lowest priority queue that is unmasked by the current TPL. It means that, within a given TPL, the notification function invocation order will reflect the enqueueing (= signaling) order. But the spec does not specify the *signaling* order for such events that belong to the same event group, when one of those events is signaled. The spec says, Event groups are collections of events identified by a shared EFI_GUID where, when one member event is signaled, all other events are signaled and their individual notification actions are taken (as described in CreateEvent). All events are guaranteed to be signaled before the first notification action is taken. All notification functions will be executed in the order specified by their NotifyTpl. So if you have two events, A and B, and they belong to the same event group G, and NotifyTpl is the same for both, then if you signal either A or B, then the notification functions may be queued, *and invoked*, in either (A, B), or (B, A), order. The invocation order will reflect the queueing order, yes, but the latter is unspecified, when you go through an event group. Thanks Laszlo
|
|