On 11/13/23 06:47, Yuanhao Xie wrote:
> SMM read save state requires AP must be present.
> This patch aim to avoid the AP not ready for save state check.
> 
> Signed-off-by: Zhihao Li <zhihao...@intel.com>
> Cc: Ray Ni <ray...@intel.com>
> Cc: Rahul Kumar <rahul1.ku...@intel.com>
> Cc: Gerd Hoffmann <kra...@redhat.com>
> ---
>  UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c     | 25 +++++++++++++++++++++++++
>  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 13 +++++++++++++
>  2 files changed, 38 insertions(+)
> 
> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c 
> b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c
> index 391b64e9f2..cdc7021ee9 100644
> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c
> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c
> @@ -406,8 +406,15 @@ SmmCpuRendezvous (
>    IN BOOLEAN                            BlockingMode
>    )
>  {
> +  UINTN       Index;
> +  UINTN       PresentCount;
> +  UINT32      BlockedCount;
> +  UINT32      DisabledCount;
>    EFI_STATUS  Status;
>  
> +  BlockedCount  = 0;
> +  DisabledCount = 0;
> +
>    //
>    // Return success immediately if all CPUs are already synchronized.
>    //
> @@ -426,6 +433,24 @@ SmmCpuRendezvous (
>      // There are some APs outside SMM, Wait for all avaiable APs to arrive.
>      //
>      SmmWaitForApArrival ();
> +
> +    //
> +    // Make sure all APs have their Present flag set
> +    //
> +    while (TRUE) {
> +      PresentCount = 0;
> +      for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
> +        if (*(mSmmMpSyncData->CpuData[Index].Present)) {
> +          PresentCount++;
> +        }
> +      }
> +
> +      GetSmmDelayedBlockedDisabledCount (NULL, &BlockedCount, 
> &DisabledCount);
> +      if (PresentCount == mMaxNumberOfCpus - BlockedCount - DisabledCount ) {
> +        break;
> +      }
> +    }
> +
>      Status = mSmmMpSyncData->AllApArrivedWithException ? EFI_SUCCESS : 
> EFI_TIMEOUT;
>    } else {
>      //

(1) Here's why I don't like this:

we already have a function that is supposed to do this, and it is
SmmWaitForApArrival().

SmmWaitForApArrival() is called in two contexts. One, in BSPHandler().
Two, here.

Consider the following condition:

  (SyncMode == SmmCpuSyncModeTradition) ||
  SmmCpuFeaturesNeedConfigureMtrrs ()

If this condition evaluates to true, then BSPHandler() calls
SmmWaitForApArrival(), and SmmCpuRendezvous() doesn't.

(This is what the "else" branch in SmmCpuRendezvous() states, in a
comment, too.)

And if the condition evaluates to false, then SmmCpuRendezvous() calls
SmmWaitForApArrival(), and BSPHandler() doesn't.

This patch adds extra waiting logic to *one* of both call sites. And I
don't understand why the *other* call site (in BSPHandler()) does not
need the exact same logic.

In my opinion, this is a sign that SmmWaitForApArrival() isn't "strong
enough". It is not doing all of the work.

In my opinion, *both* call sites should receive this logic (i.e., ensure
that all AP's are "present"), but then in turn, the additional waiting /
checking should be pushed down into SmmWaitForApArrival().

What's your opinion on that?

(2) I notice that a similar "busy loop", waiting for Present flags, is
in BSPHandler().

Do you think we could call CpuPause() in all such "busy loops" (just
before the end of the "while" body)? I think that's supposed to improve
the system's throughput, considered as a whole. The function's comment says,

  Requests CPU to pause for a short period of time. Typically used in MP
  systems to prevent memory starvation while waiting for a spin lock.


Thanks
Laszlo





> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h 
> b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
> index 20ada465c2..b5aa5f99d7 100644
> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
> @@ -1552,6 +1552,19 @@ SmmWaitForApArrival (
>    VOID
>    );
>  
> +/**
> +  Returns the Number of SMM Delayed & Blocked & Disabled Thread Count.
> +  @param[in,out] DelayedCount  The Number of SMM Delayed Thread Count.
> +  @param[in,out] BlockedCount  The Number of SMM Blocked Thread Count.
> +  @param[in,out] DisabledCount The Number of SMM Disabled Thread Count.
> +**/
> +VOID
> +GetSmmDelayedBlockedDisabledCount (
> +  IN OUT UINT32  *DelayedCount,
> +  IN OUT UINT32  *BlockedCount,
> +  IN OUT UINT32  *DisabledCount
> +  );
> +
>  /**
>    Write unprotect read-only pages if Cr0.Bits.WP is 1.
>  



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#111168): https://edk2.groups.io/g/devel/message/111168
Mute This Topic: https://groups.io/mt/102556528/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: 
https://edk2.groups.io/g/devel/leave/9847357/21656/1706620634/xyzzy 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to