public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Wu, Jiaxin" <jiaxin.wu@intel.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>,
	"lersek@redhat.com" <lersek@redhat.com>
Cc: "Dong, Eric" <eric.dong@intel.com>, "Ni, Ray" <ray.ni@intel.com>,
	"Zeng, Star" <star.zeng@intel.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	"Kumar, Rahul R" <rahul.r.kumar@intel.com>
Subject: Re: [edk2-devel] [PATCH v3 3/6] UefiCpuPkg: Implements SmmCpuSyncLib library instance
Date: Fri, 15 Dec 2023 06:41:15 +0000	[thread overview]
Message-ID: <MN0PR11MB6158C08ED923BD28B5E2CC48FE93A@MN0PR11MB6158.namprd11.prod.outlook.com> (raw)
In-Reply-To: 4a2911fb-aa15-efb0-f2e4-1c5bac8aab8d@redhat.com

I will the align the ReleaseSemaphore & WaitForSemaphore behavior as blow:

ReleaseSemaphore() prevents increase the semaphore if locked, and it should return the locked value (MAX_UINT32);  --> then we can check the return value is  MAX_UINT32 or not in SmmCpuSyncCheckInCpu(), and sem itself won't be changed.
WaitForSemaphore() prevents decrease the semaphore if locked, and it should return the locked value (MAX_UINT32); --> then we can check the return value is  MAX_UINT32 or not in SmmCpuSyncCheckOutCpu (), and sem itself won'tbe changed.

Thanks,
Jiaxin 


> -----Original Message-----
> From: Wu, Jiaxin
> Sent: Thursday, December 14, 2023 11:35 PM
> To: devel@edk2.groups.io; lersek@redhat.com
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Zeng, Star
> <star.zeng@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Kumar, Rahul R
> <rahul.r.kumar@intel.com>
> Subject: RE: [edk2-devel] [PATCH v3 3/6] UefiCpuPkg: Implements
> SmmCpuSyncLib library instance
> 
> > > The code will be changed to:
> > >
> > >   if ((INT32)InternalWaitForSemaphore (Context->CpuCount) < 0) {
> > >     return RETURN_ABORTED;
> > >   }
> >
> > I find this quite ugly. In the "semaphore post" operation, we already
> > have code that prevents incrementing if the semaphore is "locked". Can
> > we perhaps create a "semaphore pend" operation that does the same?
> >
> > How about this:
> >
> > diff --git a/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c
> > b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c
> > index 3c2835f8def6..5d7fc58ef23f 100644
> > --- a/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c
> > +++ b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c
> > @@ -91,35 +91,38 @@ UINT32
> >  InternalWaitForSemaphore (
> >    IN OUT  volatile UINT32  *Sem
> >    )
> >  {
> >    UINT32  Value;
> >
> >    for ( ; ;) {
> >      Value = *Sem;
> > +    if (Value == MAX_UINT32) {
> > +      return Value;
> > +    }
> >      if ((Value != 0) &&
> >          (InterlockedCompareExchange32 (
> >             (UINT32 *)Sem,
> >             Value,
> >             Value - 1
> >             ) == Value))
> >      {
> >        break;
> >      }
> >
> >      CpuPause ();
> >    }
> >
> >    return Value - 1;
> >  }
> >
> > Note, I'm just brainstorming here, I've not thought it through. Just to
> > illustrate the direction I'm thinking of.
> >
> > This change should be mostly OK. InternalWaitForSemaphore() returns the
> > decremented value. So, for InternalWaitForSemaphore() to return
> > MAX_UINT32 *without* this update, the function would have to decrement
> > the semaphore when the semaphore is zero. But in that case, the function
> > *blocks*. Thus, a return value of MAX_UINT32 is not possible without
> > this extension; ergo, if MAX_UINT32 is returned (with this extension),
> 
> Yes, that's for the semaphore sync usage, we have to block the sem if it's zero,
> decrease it when return. That's why I said - it's naturally make sure the Run is
> reset after all ready to exit.  Then it can achieve the below flow:
>     BSP: ReleaseOneAp  -->  AP: WaitForBsp
>     BSP: WaitForAPs    <--  AP: ReleaseBsp
> 
> 
> For locked case, I just copy the existing logic from SMM cpu driver (as I
> document in the commit message: The instance refers the existing SMM CPU
> driver (PiSmmCpuDxeSmm) sync implementation and behavior):
> existing ReleaseSemaphore() prevents increase the semaphore, but it still
> return the original semaphore value +1; --> that's why we have to check the
> return value is  0 or not in SmmCpuSyncCheckInCpu()
> existing WaitForSemaphore() allow decrease the semaphore if locked, and it
> also return the original semaphore value -1;  --> that's why we have to check
> the return value is  < 0 or not in SmmCpuSyncCheckOutCpu()
> 
> so, do you want to align the behavior as below?
> 
> ReleaseSemaphore() prevents increase the semaphore if locked, and it should
> return the locked value (MAX_UINT32);  --> then we can check the return
> value is  MAX_UINT32 or not in SmmCpuSyncCheckInCpu(), and sem itself
> won't be changed.
> WaitForSemaphore() prevents decrease the semaphore if locked, and it should
> return the locked value (MAX_UINT32); --> then we can check the return value
> is  MAX_UINT32 or not in SmmCpuSyncCheckOutCpu (), and sem itself won't
> be changed.
> 
> I think:
> for ReleaseSemaphore, it must meet below 2 cases usage:
> 1. for semaphore sync usage (Run), it doesn't care the lock case, and returned
> value is not cared. Just check the semaphore itself.
> 2. for Rendezvous case (Counter), it not only needs to check locked or not
> from return value, but also require "only increase the semaphore if not
> locked".
> 
> for WaitForSemaphore, it must meet below 2 cases usage:
> 1. for semaphore sync usage (Run), it doesn't care the lock case, and returned
> value is not cared. But for the semaphore itself, it need block at 0, and
> decrease when return.
> 2. for Rendezvous case (Counter), it only needs to check locked or not from
> return value. semaphore itself is not cared.
> 
> So, based on above, I think, yes, we can do the change to align the lock
> behavior:
> 
> /**
>   Performs an atomic compare exchange operation to get semaphore.
>   The compare exchange operation must be performed using MP safe
>   mechanisms.
> 
>   @param[in,out]  Sem    IN:  32-bit unsigned integer
>                          OUT: original integer - 1 if Sem is not locked.
>                          OUT: original integer (MAX_UINT32) if Sem is locked.
> 
>   @retval     Original integer - 1 if Sem is not locked.
>               Original integer (MAX_UINT32) if Sem is locked.
> 
> **/
> STATIC
> UINT32
> InternalWaitForSemaphore (
>   IN OUT  volatile UINT32  *Sem
>   )
> {
>   UINT32  Value;
> 
>   for ( ; ;) {
>     Value = *Sem;
>     if (Value == MAX_UINT32) {
>       return Value;
>     }
> 
>     if ((Value != 0) &&
>         (InterlockedCompareExchange32 (
>            (UINT32 *)Sem,
>            Value,
>            Value - 1
>            ) == Value))
>     {
>       break;
>     }
> 
>     CpuPause ();
>   }
> 
>   return Value - 1;
> }
> 
> /**
>   Performs an atomic compare exchange operation to release semaphore.
>   The compare exchange operation must be performed using MP safe
>   mechanisms.
> 
>   @param[in,out]  Sem    IN:  32-bit unsigned integer
>                          OUT: original integer + 1 if Sem is not locked.
>                          OUT: original integer (MAX_UINT32) if Sem is locked.
> 
>   @retval    Original integer + 1 if Sem is not locked.
>              Original integer (MAX_UINT32) if Sem is locked.
> 
> **/
> STATIC
> UINT32
> InternalReleaseSemaphore (
>   IN OUT  volatile UINT32  *Sem
>   )
> {
>   UINT32  Value;
> 
>   do {
>     Value = *Sem;
>   } while (Value + 1 != 0 &&
>            InterlockedCompareExchange32 (
>              (UINT32 *)Sem,
>              Value,
>              Value + 1
>              ) != Value);
> 
>   if (Value == MAX_UINT32) {
>     return Value;
>   }
> 
>   return Value + 1;
> }
> 
> I haven't see any issue with this change.
> 
> > we know the door was locked earlier (and the semaphore is not changed).
> >
> > At the same time, we might want to update InternalReleaseSemaphore() as
> > well, so that it cannot validly increment the semaphore value to
> MAX_UINT32.
> >
> >
> >
> > >
> > >



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#112585): https://edk2.groups.io/g/devel/message/112585
Mute This Topic: https://groups.io/mt/103010165/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2023-12-15  6:41 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-06 10:01 [edk2-devel] [PATCH v3 0/6] Refine SMM CPU Sync flow and abstract SmmCpuSyncLib Wu, Jiaxin
2023-12-06 10:01 ` [edk2-devel] [PATCH v3 1/6] UefiCpuPkg/PiSmmCpuDxeSmm: Optimize Semaphore Sync between BSP and AP Wu, Jiaxin
2023-12-12 19:27   ` Laszlo Ersek
2023-12-06 10:01 ` [edk2-devel] [PATCH v3 2/6] UefiCpuPkg: Adds SmmCpuSyncLib library class Wu, Jiaxin
2023-12-07  9:07   ` Ni, Ray
2023-12-12 20:18   ` Laszlo Ersek
2023-12-13  4:23     ` Wu, Jiaxin
2023-12-13 15:02       ` Laszlo Ersek
2023-12-06 10:01 ` [edk2-devel] [PATCH v3 3/6] UefiCpuPkg: Implements SmmCpuSyncLib library instance Wu, Jiaxin
2023-12-13 14:34   ` Laszlo Ersek
2023-12-14 11:11     ` Wu, Jiaxin
2023-12-14 13:48       ` Laszlo Ersek
2023-12-14 15:34         ` Wu, Jiaxin
2023-12-14 15:54         ` Wu, Jiaxin
2023-12-15  6:41         ` Wu, Jiaxin [this message]
2023-12-15  6:44         ` Wu, Jiaxin
2023-12-06 10:01 ` [edk2-devel] [PATCH v3 4/6] OvmfPkg: Specifies SmmCpuSyncLib instance Wu, Jiaxin
2023-12-13 16:52   ` Laszlo Ersek
2023-12-14 13:43     ` Wu, Jiaxin
2023-12-15  0:21     ` Ni, Ray
2023-12-06 10:01 ` [edk2-devel] [PATCH v3 5/6] UefiPayloadPkg: " Wu, Jiaxin
2023-12-06 10:01 ` [edk2-devel] [PATCH v3 6/6] UefiCpuPkg/PiSmmCpuDxeSmm: Consume SmmCpuSyncLib Wu, Jiaxin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=MN0PR11MB6158C08ED923BD28B5E2CC48FE93A@MN0PR11MB6158.namprd11.prod.outlook.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox