public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [Patch 1/2] UefiCpuPkg/MpInitLib: Not use disabled AP.
@ 2018-06-28 11:29 Eric Dong
  2018-06-28 11:29 ` [Patch 2/2] UefiCpuPkg/MpInitLib: Remove redundant parameter Eric Dong
  0 siblings, 1 reply; 5+ messages in thread
From: Eric Dong @ 2018-06-28 11:29 UTC (permalink / raw)
  To: edk2-devel; +Cc: Ruiyu Ni, Jeff Fan, Laszlo Ersek

Based on PI spec description, disabled APs should not been
include in the StartupAllAPs task. Current implementation always 
change AP state to CpuStateReady in WakeUpAP function which also
let Disabled APs to do the task. 

This patch reduce the CPU state to only three state: Idle, busy
and disabled. The possible change process is:
Idel -> busy -> Idle
Idle -> disabled -> Idle

Done Tests:
1.PI SCT Test
2.Boot OS / S3

Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jeff Fan <vanjeff_919@hotmail.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Eric Dong <eric.dong@intel.com>
---
 UefiCpuPkg/Library/MpInitLib/MpLib.c | 34 +++++++++++++---------------------
 UefiCpuPkg/Library/MpInitLib/MpLib.h |  2 --
 2 files changed, 13 insertions(+), 23 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index f2ff40417a..3945771764 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -460,8 +460,6 @@ CollectProcessorCount (
   IN CPU_MP_DATA         *CpuMpData
   )
 {
-  UINTN                  Index;
-
   //
   // Send 1st broadcast IPI to APs to wakeup APs
   //
@@ -499,12 +497,6 @@ CollectProcessorCount (
     // Enable x2APIC on BSP
     //
     SetApicMode (LOCAL_APIC_MODE_X2APIC);
-    //
-    // Set BSP/Aps state to IDLE
-    //
-    for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
-      SetApState (&CpuMpData->CpuData[Index], CpuStateIdle);
-    }
   }
   DEBUG ((DEBUG_INFO, "APIC MODE is %d\n", GetApicMode ()));
   //
@@ -648,7 +640,7 @@ ApWakeupFunction (
         CpuFlushTlb ();
       }
 
-      if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateReady) {
+      if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateIdle) {
         Procedure = (EFI_AP_PROCEDURE)CpuMpData->CpuData[ProcessorNumber].ApFunction;
         Parameter = (VOID *) CpuMpData->CpuData[ProcessorNumber].ApFunctionArgument;
         if (Procedure != NULL) {
@@ -691,7 +683,7 @@ ApWakeupFunction (
             }
           }
         }
-        SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateFinished);
+        SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);
       }
     }
 
@@ -1005,7 +997,6 @@ WakeUpAP (
         CpuData = &CpuMpData->CpuData[Index];
         CpuData->ApFunction         = (UINTN) Procedure;
         CpuData->ApFunctionArgument = (UINTN) ProcedureArgument;
-        SetApState (CpuData, CpuStateReady);
         if (CpuMpData->InitFlag != ApInitConfig) {
           *(UINT32 *) CpuData->StartupApSignal = WAKEUP_AP_SIGNAL;
         }
@@ -1052,7 +1043,6 @@ WakeUpAP (
     CpuData = &CpuMpData->CpuData[ProcessorNumber];
     CpuData->ApFunction         = (UINTN) Procedure;
     CpuData->ApFunctionArgument = (UINTN) ProcedureArgument;
-    SetApState (CpuData, CpuStateReady);
     //
     // Wakeup specified AP
     //
@@ -1345,11 +1335,10 @@ CheckThisAP (
   //
   // If the AP finishes for StartupThisAP(), return EFI_SUCCESS.
   //
-  if (GetApState(CpuData) == CpuStateFinished) {
+  if (GetApState(CpuData) != CpuStateBusy) {
     if (CpuData->Finished != NULL) {
       *(CpuData->Finished) = TRUE;
     }
-    SetApState (CpuData, CpuStateIdle);
     return EFI_SUCCESS;
   } else {
     //
@@ -1410,10 +1399,9 @@ CheckAllAPs (
     // Only BSP and corresponding AP access this unit of CPU Data. This means the AP will not modify the
     // value of state after setting the it to CpuStateFinished, so BSP can safely make use of its value.
     //
-    if (GetApState(CpuData) == CpuStateFinished) {
+    if (GetApState(CpuData) != CpuStateBusy) {
       CpuMpData->RunningCount ++;
       CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;
-      SetApState(CpuData, CpuStateIdle);
 
       //
       // If in Single Thread mode, then search for the next waiting AP for execution.
@@ -1625,6 +1613,13 @@ MpInitLibInitialize (
         );
     }
     if (MaxLogicalProcessorNumber > 1) {
+      //
+      // Initial AP to idle state, later ApWakeupFunction based on 
+      // this state to decide whether need to execute AP procedure.
+      //
+      for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
+        SetApState (&CpuMpData->CpuData[Index], CpuStateIdle);
+      }
       //
       // Wakeup APs to do some AP initialize sync
       //
@@ -1636,9 +1631,6 @@ MpInitLibInitialize (
         CpuPause ();
       }
       CpuMpData->InitFlag = ApInitDone;
-      for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
-        SetApState (&CpuMpData->CpuData[Index], CpuStateIdle);
-      }
     }
   }
 
@@ -1838,7 +1830,7 @@ SwitchBSPWorker (
   //
   // Wait for old BSP finished AP task
   //
-  while (GetApState (&CpuMpData->CpuData[CallerNumber]) != CpuStateFinished) {
+  while (GetApState (&CpuMpData->CpuData[CallerNumber]) == CpuStateBusy) {
     CpuPause ();
   }
 
@@ -2112,7 +2104,7 @@ StartupAllAPsWorker (
       ApState = GetApState (CpuData);
       if (ApState != CpuStateDisabled) {
         HasEnabledAp = TRUE;
-        if (ApState != CpuStateIdle) {
+        if (ApState == CpuStateBusy) {
           //
           // If any enabled APs are busy, return EFI_NOT_READY.
           //
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index e7f9a4de0a..90c09fb8fb 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -83,9 +83,7 @@ typedef enum {
 //
 typedef enum {
   CpuStateIdle,
-  CpuStateReady,
   CpuStateBusy,
-  CpuStateFinished,
   CpuStateDisabled
 } CPU_STATE;
 
-- 
2.15.0.windows.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Patch 2/2] UefiCpuPkg/MpInitLib: Remove redundant parameter.
  2018-06-28 11:29 [Patch 1/2] UefiCpuPkg/MpInitLib: Not use disabled AP Eric Dong
@ 2018-06-28 11:29 ` Eric Dong
  2018-06-28 15:37   ` Laszlo Ersek
  0 siblings, 1 reply; 5+ messages in thread
From: Eric Dong @ 2018-06-28 11:29 UTC (permalink / raw)
  To: edk2-devel; +Cc: Ruiyu Ni, Jeff Fan, Laszlo Ersek

Parameter StartCount duplicates with RunningCount. After this change,
RunningCount means the running AP count.

Done Tests:
1.PI SCT Test
2.Boot OS / S3

Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jeff Fan <vanjeff_919@hotmail.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Eric Dong <eric.dong@intel.com>
---
 UefiCpuPkg/Library/MpInitLib/MpLib.c | 11 +++++------
 UefiCpuPkg/Library/MpInitLib/MpLib.h |  1 -
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 3945771764..52c9679099 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1400,7 +1400,7 @@ CheckAllAPs (
     // value of state after setting the it to CpuStateFinished, so BSP can safely make use of its value.
     //
     if (GetApState(CpuData) != CpuStateBusy) {
-      CpuMpData->RunningCount ++;
+      CpuMpData->RunningCount --;
       CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;
 
       //
@@ -1425,7 +1425,7 @@ CheckAllAPs (
   //
   // If all APs finish, return EFI_SUCCESS.
   //
-  if (CpuMpData->RunningCount == CpuMpData->StartCount) {
+  if (CpuMpData->RunningCount == 0) {
     return EFI_SUCCESS;
   }
 
@@ -1442,7 +1442,7 @@ CheckAllAPs (
     //
     if (CpuMpData->FailedCpuList != NULL) {
       *CpuMpData->FailedCpuList =
-         AllocatePool ((CpuMpData->StartCount - CpuMpData->FinishedCount + 1) * sizeof (UINTN));
+         AllocatePool ((CpuMpData->RunningCount + 1) * sizeof (UINTN));
       ASSERT (*CpuMpData->FailedCpuList != NULL);
     }
     ListIndex = 0;
@@ -2121,7 +2121,7 @@ StartupAllAPsWorker (
     return EFI_NOT_STARTED;
   }
 
-  CpuMpData->StartCount = 0;
+  CpuMpData->RunningCount = 0;
   for (ProcessorNumber = 0; ProcessorNumber < ProcessorCount; ProcessorNumber++) {
     CpuData = &CpuMpData->CpuData[ProcessorNumber];
     CpuData->Waiting = FALSE;
@@ -2131,7 +2131,7 @@ StartupAllAPsWorker (
         // Mark this processor as responsible for current calling.
         //
         CpuData->Waiting = TRUE;
-        CpuMpData->StartCount++;
+        CpuMpData->RunningCount++;
       }
     }
   }
@@ -2140,7 +2140,6 @@ StartupAllAPsWorker (
   CpuMpData->ProcArguments = ProcedureArgument;
   CpuMpData->SingleThread  = SingleThread;
   CpuMpData->FinishedCount = 0;
-  CpuMpData->RunningCount  = 0;
   CpuMpData->FailedCpuList = FailedCpuList;
   CpuMpData->ExpectedTime  = CalculateTimeout (
                                TimeoutInMicroseconds,
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 90c09fb8fb..4166734687 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -210,7 +210,6 @@ struct _CPU_MP_DATA {
   UINTN                          BackupBuffer;
   UINTN                          BackupBufferSize;
 
-  volatile UINT32                StartCount;
   volatile UINT32                FinishedCount;
   volatile UINT32                RunningCount;
   BOOLEAN                        SingleThread;
-- 
2.15.0.windows.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Patch 2/2] UefiCpuPkg/MpInitLib: Remove redundant parameter.
  2018-06-28 11:29 ` [Patch 2/2] UefiCpuPkg/MpInitLib: Remove redundant parameter Eric Dong
@ 2018-06-28 15:37   ` Laszlo Ersek
  2018-06-29  1:48     ` Dong, Eric
  0 siblings, 1 reply; 5+ messages in thread
From: Laszlo Ersek @ 2018-06-28 15:37 UTC (permalink / raw)
  To: Eric Dong, edk2-devel; +Cc: Ruiyu Ni

Hi Eric,

On 06/28/18 13:29, Eric Dong wrote:
> Parameter StartCount duplicates with RunningCount. After this change,
> RunningCount means the running AP count.
>
> Done Tests:
> 1.PI SCT Test
> 2.Boot OS / S3
>
> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
> Cc: Jeff Fan <vanjeff_919@hotmail.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Eric Dong <eric.dong@intel.com>
> ---
>  UefiCpuPkg/Library/MpInitLib/MpLib.c | 11 +++++------
>  UefiCpuPkg/Library/MpInitLib/MpLib.h |  1 -
>  2 files changed, 5 insertions(+), 7 deletions(-)
>
> diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
> index 3945771764..52c9679099 100644
> --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
> +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
> @@ -1400,7 +1400,7 @@ CheckAllAPs (
>      // value of state after setting the it to CpuStateFinished, so BSP can safely make use of its value.
>      //
>      if (GetApState(CpuData) != CpuStateBusy) {
> -      CpuMpData->RunningCount ++;
> +      CpuMpData->RunningCount --;
>        CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;
>
>        //
> @@ -1425,7 +1425,7 @@ CheckAllAPs (
>    //
>    // If all APs finish, return EFI_SUCCESS.
>    //
> -  if (CpuMpData->RunningCount == CpuMpData->StartCount) {
> +  if (CpuMpData->RunningCount == 0) {
>      return EFI_SUCCESS;
>    }
>
> @@ -1442,7 +1442,7 @@ CheckAllAPs (
>      //
>      if (CpuMpData->FailedCpuList != NULL) {
>        *CpuMpData->FailedCpuList =
> -         AllocatePool ((CpuMpData->StartCount - CpuMpData->FinishedCount + 1) * sizeof (UINTN));
> +         AllocatePool ((CpuMpData->RunningCount + 1) * sizeof (UINTN));
>        ASSERT (*CpuMpData->FailedCpuList != NULL);
>      }
>      ListIndex = 0;
> @@ -2121,7 +2121,7 @@ StartupAllAPsWorker (
>      return EFI_NOT_STARTED;
>    }
>
> -  CpuMpData->StartCount = 0;
> +  CpuMpData->RunningCount = 0;
>    for (ProcessorNumber = 0; ProcessorNumber < ProcessorCount; ProcessorNumber++) {
>      CpuData = &CpuMpData->CpuData[ProcessorNumber];
>      CpuData->Waiting = FALSE;
> @@ -2131,7 +2131,7 @@ StartupAllAPsWorker (
>          // Mark this processor as responsible for current calling.
>          //
>          CpuData->Waiting = TRUE;
> -        CpuMpData->StartCount++;
> +        CpuMpData->RunningCount++;
>        }
>      }
>    }
> @@ -2140,7 +2140,6 @@ StartupAllAPsWorker (
>    CpuMpData->ProcArguments = ProcedureArgument;
>    CpuMpData->SingleThread  = SingleThread;
>    CpuMpData->FinishedCount = 0;
> -  CpuMpData->RunningCount  = 0;
>    CpuMpData->FailedCpuList = FailedCpuList;
>    CpuMpData->ExpectedTime  = CalculateTimeout (
>                                 TimeoutInMicroseconds,
> diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
> index 90c09fb8fb..4166734687 100644
> --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
> +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
> @@ -210,7 +210,6 @@ struct _CPU_MP_DATA {
>    UINTN                          BackupBuffer;
>    UINTN                          BackupBufferSize;
>
> -  volatile UINT32                StartCount;
>    volatile UINT32                FinishedCount;
>    volatile UINT32                RunningCount;
>    BOOLEAN                        SingleThread;
>

I'm currently missing a good understanding of how these counters are
modified. They are all qualified "volatile", which suggests they are
accessed from multiple processors. Is that correct?

Here's my concern: assume we have 3 APs, and we maintain how many of
them are running concurrently at any given point. Assume we start them
up all at once, and then later they all finish. The modified
"RunningCount" value might advance like this:

  AP#1  AP#2  AP#3  RunningCount  comment
  ----  ----  ----  ------------  ----------------
                    0             no AP running yet
   v                1             AP#1 starts
   |     v          2             AP#2 starts
   |     |     v    3             AP#3 starts
   |     |     |    3             all APs working
   |     ^     |    2             AP#2 finishes
   |           ^    1             AP#3 finishes
   ^                0             AP#1 finishes, done

However, the following could happen as well:

  AP#1  AP#2  AP#3  RunningCount  comment
  ----  ----  ----  ------------  ----------------
                    0             no AP running yet
   v                1             AP#1 starts
   ^                0             AP#1 finishes
         v          1             AP#2 starts
         |     v    2             AP#3 starts
         |     ^    1             AP#3 finishes
         ^          0             AP#2 finishes, done

In the second scheduling, we get RunningCount=0 when AP#1 finishes, even
though AP#2 and AP#3 are not done (they haven't even started yet).

Is this a realistic concern, or is the above scenario impossible?

(I'd like to test the series after understanding this.)

Actually... if the problem scenario is possible, I think it could affect
the current (pre-patch) code as well. I hope I'm wrong!

Thanks,
Laszlo


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Patch 2/2] UefiCpuPkg/MpInitLib: Remove redundant parameter.
  2018-06-28 15:37   ` Laszlo Ersek
@ 2018-06-29  1:48     ` Dong, Eric
  2018-06-29  7:19       ` Laszlo Ersek
  0 siblings, 1 reply; 5+ messages in thread
From: Dong, Eric @ 2018-06-29  1:48 UTC (permalink / raw)
  To: Laszlo Ersek, edk2-devel@lists.01.org; +Cc: Ni, Ruiyu

Hi Laszlo,

> -----Original Message-----
> From: Laszlo Ersek [mailto:lersek@redhat.com]
> Sent: Thursday, June 28, 2018 11:37 PM
> To: Dong, Eric <eric.dong@intel.com>; edk2-devel@lists.01.org
> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>
> Subject: Re: [edk2] [Patch 2/2] UefiCpuPkg/MpInitLib: Remove redundant
> parameter.
> 
> Hi Eric,
> 
> On 06/28/18 13:29, Eric Dong wrote:
> > Parameter StartCount duplicates with RunningCount. After this change,
> > RunningCount means the running AP count.
> >
> > Done Tests:
> > 1.PI SCT Test
> > 2.Boot OS / S3
> >
> > Cc: Ruiyu Ni <ruiyu.ni@intel.com>
> > Cc: Jeff Fan <vanjeff_919@hotmail.com>
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Contributed-under: TianoCore Contribution Agreement 1.1
> > Signed-off-by: Eric Dong <eric.dong@intel.com>
> > ---
> >  UefiCpuPkg/Library/MpInitLib/MpLib.c | 11 +++++------
> > UefiCpuPkg/Library/MpInitLib/MpLib.h |  1 -
> >  2 files changed, 5 insertions(+), 7 deletions(-)
> >
> > diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c
> > b/UefiCpuPkg/Library/MpInitLib/MpLib.c
> > index 3945771764..52c9679099 100644
> > --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
> > +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
> > @@ -1400,7 +1400,7 @@ CheckAllAPs (
> >      // value of state after setting the it to CpuStateFinished, so BSP can safely
> make use of its value.
> >      //
> >      if (GetApState(CpuData) != CpuStateBusy) {
> > -      CpuMpData->RunningCount ++;
> > +      CpuMpData->RunningCount --;
> >        CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;
> >
> >        //
> > @@ -1425,7 +1425,7 @@ CheckAllAPs (
> >    //
> >    // If all APs finish, return EFI_SUCCESS.
> >    //
> > -  if (CpuMpData->RunningCount == CpuMpData->StartCount) {
> > +  if (CpuMpData->RunningCount == 0) {
> >      return EFI_SUCCESS;
> >    }
> >
> > @@ -1442,7 +1442,7 @@ CheckAllAPs (
> >      //
> >      if (CpuMpData->FailedCpuList != NULL) {
> >        *CpuMpData->FailedCpuList =
> > -         AllocatePool ((CpuMpData->StartCount - CpuMpData->FinishedCount
> + 1) * sizeof (UINTN));
> > +         AllocatePool ((CpuMpData->RunningCount + 1) * sizeof
> > + (UINTN));
> >        ASSERT (*CpuMpData->FailedCpuList != NULL);
> >      }
> >      ListIndex = 0;
> > @@ -2121,7 +2121,7 @@ StartupAllAPsWorker (
> >      return EFI_NOT_STARTED;
> >    }
> >
> > -  CpuMpData->StartCount = 0;
> > +  CpuMpData->RunningCount = 0;
> >    for (ProcessorNumber = 0; ProcessorNumber < ProcessorCount;
> ProcessorNumber++) {
> >      CpuData = &CpuMpData->CpuData[ProcessorNumber];
> >      CpuData->Waiting = FALSE;
> > @@ -2131,7 +2131,7 @@ StartupAllAPsWorker (
> >          // Mark this processor as responsible for current calling.
> >          //
> >          CpuData->Waiting = TRUE;
> > -        CpuMpData->StartCount++;
> > +        CpuMpData->RunningCount++;
> >        }
> >      }
> >    }
> > @@ -2140,7 +2140,6 @@ StartupAllAPsWorker (
> >    CpuMpData->ProcArguments = ProcedureArgument;
> >    CpuMpData->SingleThread  = SingleThread;
> >    CpuMpData->FinishedCount = 0;
> > -  CpuMpData->RunningCount  = 0;
> >    CpuMpData->FailedCpuList = FailedCpuList;
> >    CpuMpData->ExpectedTime  = CalculateTimeout (
> >                                 TimeoutInMicroseconds, diff --git
> > a/UefiCpuPkg/Library/MpInitLib/MpLib.h
> > b/UefiCpuPkg/Library/MpInitLib/MpLib.h
> > index 90c09fb8fb..4166734687 100644
> > --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
> > +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
> > @@ -210,7 +210,6 @@ struct _CPU_MP_DATA {
> >    UINTN                          BackupBuffer;
> >    UINTN                          BackupBufferSize;
> >
> > -  volatile UINT32                StartCount;
> >    volatile UINT32                FinishedCount;
> >    volatile UINT32                RunningCount;
> >    BOOLEAN                        SingleThread;
> >
> 
> I'm currently missing a good understanding of how these counters are
> modified. They are all qualified "volatile", which suggests they are accessed
> from multiple processors. Is that correct?

No, actually only FinishedCount is changed by BSP and Aps, other two are only changed by BSP. StartCount stands for the AP count which will do the task. It is calculated by BSP before Aps start the task. RunningCount stands for the AP count which have finished the task. It also detected and changed by BSP.

> 
> Here's my concern: assume we have 3 APs, and we maintain how many of
> them are running concurrently at any given point. Assume we start them up
> all at once, and then later they all finish. The modified "RunningCount" value
> might advance like this:
> 
>   AP#1  AP#2  AP#3  RunningCount  comment
>   ----  ----  ----  ------------  ----------------
>                     0             no AP running yet
>    v                1             AP#1 starts
>    |     v          2             AP#2 starts
>    |     |     v    3             AP#3 starts
>    |     |     |    3             all APs working
>    |     ^     |    2             AP#2 finishes
>    |           ^    1             AP#3 finishes
>    ^                0             AP#1 finishes, done
> 
> However, the following could happen as well:
> 
>   AP#1  AP#2  AP#3  RunningCount  comment
>   ----  ----  ----  ------------  ----------------
>                     0             no AP running yet
>    v                1             AP#1 starts
>    ^                0             AP#1 finishes
>          v          1             AP#2 starts
>          |     v    2             AP#3 starts
>          |     ^    1             AP#3 finishes
>          ^          0             AP#2 finishes, done
> 
> In the second scheduling, we get RunningCount=0 when AP#1 finishes, even
> though AP#2 and AP#3 are not done (they haven't even started yet).
> 
> Is this a realistic concern, or is the above scenario impossible?

For this patch, RunningCount is calculated by BSP before it start the task for Aps, so how the Aps start the task will not impact the logic.  The update of RunningCount also done by BSP.

I will update the patch to remove the volatile for RunningCount.

> 
> (I'd like to test the series after understanding this.)
> 
> Actually... if the problem scenario is possible, I think it could affect the current
> (pre-patch) code as well. I hope I'm wrong!
> 
> Thanks,
> Laszlo

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Patch 2/2] UefiCpuPkg/MpInitLib: Remove redundant parameter.
  2018-06-29  1:48     ` Dong, Eric
@ 2018-06-29  7:19       ` Laszlo Ersek
  0 siblings, 0 replies; 5+ messages in thread
From: Laszlo Ersek @ 2018-06-29  7:19 UTC (permalink / raw)
  To: Dong, Eric, edk2-devel@lists.01.org; +Cc: Ni, Ruiyu

On 06/29/18 03:48, Dong, Eric wrote:
> Hi Laszlo,
>
>> -----Original Message-----
>> From: Laszlo Ersek [mailto:lersek@redhat.com]

>> I'm currently missing a good understanding of how these counters are
>> modified. They are all qualified "volatile", which suggests they are
>> accessed from multiple processors. Is that correct?
>
> No, actually only FinishedCount is changed by BSP and Aps, other two
> are only changed by BSP. StartCount stands for the AP count which will
> do the task. It is calculated by BSP before Aps start the task.
> RunningCount stands for the AP count which have finished the task. It
> also detected and changed by BSP.

> I will update the patch to remove the volatile for RunningCount.

Highly appreciated!
Laszlo


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-06-29  7:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-28 11:29 [Patch 1/2] UefiCpuPkg/MpInitLib: Not use disabled AP Eric Dong
2018-06-28 11:29 ` [Patch 2/2] UefiCpuPkg/MpInitLib: Remove redundant parameter Eric Dong
2018-06-28 15:37   ` Laszlo Ersek
2018-06-29  1:48     ` Dong, Eric
2018-06-29  7:19       ` Laszlo Ersek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox