On 10/29/15 02:32, Jordan Justen wrote: > Since the CpuDxe has a fixed maximum number of APs that are controlled > with PcdCpuMaxLogicalProcessorNumber, if the maximum number of APs are > awake, then the BSP should be able to continue. > > Since the APs may be updating the mMpSystemData.NumberOfProcessors > during this early init phase, we use SynchronizationLib to update this > variable on the AP and to read it on the BSP. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Jordan Justen <jordan.l.jus...@intel.com> > Cc: Jeff Fan <jeff....@intel.com> > Cc: Laszlo Ersek <ler...@redhat.com> > --- > UefiCpuPkg/CpuDxe/CpuMp.c | 15 ++++++++++++--- > UefiCpuPkg/CpuDxe/CpuMp.h | 2 +- > 2 files changed, 13 insertions(+), 4 deletions(-) > > diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c > index 6a22b9d..1094292 100644 > --- a/UefiCpuPkg/CpuDxe/CpuMp.c > +++ b/UefiCpuPkg/CpuDxe/CpuMp.c > @@ -1474,7 +1474,7 @@ ApEntryPointInC ( > // Store the Stack address, when reset the AP, We can found the original > address. > // > mMpSystemData.CpuDatas[mMpSystemData.NumberOfProcessors].TopOfStack = > TopOfApStack; > - mMpSystemData.NumberOfProcessors++; > + InterlockedIncrement (&mMpSystemData.NumberOfProcessors); > mMpSystemData.NumberOfEnabledProcessors++; > } else { > Status = WhoAmI (&mMpServicesTemplate, &ProcessorNumber); > @@ -1749,9 +1749,18 @@ InitializeMpSupport ( > StartApsStackless (); > > // > - // Wait for APs to arrive at the ApEntryPoint routine > + // Wait for all APs to start > // > - MicroSecondDelay (PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds)); > + Timeout = 0; > + do { > + if (InterlockedCompareExchange32 ( > + &mMpSystemData.NumberOfProcessors, 0, 0) >= > + gMaxLogicalProcessorNumber) { > + break; > + }
I suggest to add a CpuPause() call here. I think it might help on physical platforms too, but it definitely helps on hypervisors / PCPUs that support Pause Loop Exiting. The CpuPause() call will likely make each iteration of this loop to take longer, but gPollInterval below is a lower bound anyway. Anyway, this is just an idea. With or without CpuPause(): Reviewed-by: Laszlo Ersek <ler...@redhat.com> Thanks Laszlo > + MicroSecondDelay (gPollInterval); > + Timeout += gPollInterval; > + } while (Timeout <= PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds)); > } > > DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", > mMpSystemData.NumberOfProcessors)); > diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h > index 503f3ae..ab7a7f5 100644 > --- a/UefiCpuPkg/CpuDxe/CpuMp.h > +++ b/UefiCpuPkg/CpuDxe/CpuMp.h > @@ -114,7 +114,7 @@ typedef struct { > **/ > typedef struct { > CPU_DATA_BLOCK *CpuDatas; > - UINTN NumberOfProcessors; > + UINT32 NumberOfProcessors; > UINTN NumberOfEnabledProcessors; > > EFI_AP_PROCEDURE Procedure; > _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel