On 11/24/16 19:32, Igor Mammedov wrote: > On Thu, 24 Nov 2016 10:36:38 +0100 > Laszlo Ersek <[email protected]> wrote: > >> On 11/24/16 02:18, Fan, Jeff wrote: >>> Laszlo, >>> >>> Please use existing PcdCpuMaxLogicalProcessorNumber firstly. >> >> Okay, I will submit a new version of the series with this change. > Using present count of CPUs might potentially break things if > there were hotplugged CPUs with follow up S3 and wakeup dute this code: > > MpInitLibInitialize() > OldCpuMpData = GetCpuMpDataFromGuidedHob (); > > if (OldCpuMpData == NULL) { > > MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber); > > } else { > > MaxLogicalProcessorNumber = OldCpuMpData->CpuCount; > > }
Yes, this is a correct assessment. And, we're aware of it in general; I raised the same scenario in my previous email. It seems that Jeff prefers the simpler solution for now. The hotplug case is tracked by <https://bugzilla.tianocore.org/show_bug.cgi?id=251>. Thanks Laszlo > I've traced this part of code under QEMU with PcdCpuMaxLogicalProcessorNumber > set to present number of CPUs and currently OldCpuMpData is always NULL on > resume > so PcdCpuMaxLogicalProcessorNumber gets updated CPU count from platform and > it resumes seemingly fine but I won't bet that it's correct. > > here is a patch I've used for this experiment: > > diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc > index 3f4d42d..ce80690 100644 > --- a/OvmfPkg/OvmfPkgIa32.dsc > +++ b/OvmfPkg/OvmfPkgIa32.dsc > @@ -455,6 +455,7 @@ > > ################################################################################ > > [PcdsDynamicDefault] > + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|10 > gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0 > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0 > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0 > diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc > index 5688475..f7697b1 100644 > --- a/OvmfPkg/OvmfPkgIa32X64.dsc > +++ b/OvmfPkg/OvmfPkgIa32X64.dsc > @@ -461,6 +461,7 @@ > > ################################################################################ > > [PcdsDynamicDefault] > + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|10 > gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0 > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0 > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0 > diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc > index dcf64b9..4034989 100644 > --- a/OvmfPkg/OvmfPkgX64.dsc > +++ b/OvmfPkg/OvmfPkgX64.dsc > @@ -460,6 +460,7 @@ > > ################################################################################ > > [PcdsDynamicDefault] > + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|10 > gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0 > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0 > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0 > diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c > index d00a570..e205fe7 100644 > --- a/OvmfPkg/PlatformPei/MemDetect.c > +++ b/OvmfPkg/PlatformPei/MemDetect.c > @@ -342,6 +342,7 @@ PublishPeiMemory ( > UINT64 MemorySize; > UINT32 LowerMemorySize; > UINT32 PeiMemoryCap; > + UINT16 CpuCount; > > LowerMemorySize = GetSystemMemorySizeBelow4gb (); > if (FeaturePcdGet (PcdSmmSmramRequire)) { > @@ -351,6 +352,12 @@ PublishPeiMemory ( > LowerMemorySize -= FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB; > } > > + QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount); > + //QemuFwCfgSelectItem (QemuFwCfgItemMaximumCpuCount); > + CpuCount = QemuFwCfgRead16 (); > + Status = PcdSet32S(PcdCpuMaxLogicalProcessorNumber, CpuCount); > + DEBUG ((EFI_D_INFO, "XXXXXXXXXXXXXX: QemuFwCfgItemSmpCpuCount: %u\n", > CpuCount)); > + > // > // If S3 is supported, then the S3 permanent PEI memory is placed next, > // downwards. Its size is primarily dictated by CpuMpPei. The formula below > >>> So, for the platforms do not support CPU hot-plug. It could benefit the >>> boot performance. >>> For the platforms supporting CPU hot-plug. It will have no any impact. >>> >>> Introducing new PCD is good idea to benefit boot performance on S3 path, >>> but it is some complex. >>> For example, if DXE phase disables some CPU and do reboot. Real platform >>> may need another policy to set this PCD used by PEI phase. >>> >>> Could you file one bugzilla for this new PCD requirement? >> >> I filed <https://bugzilla.tianocore.org/show_bug.cgi?id=251> and >> assigned it to you; I hope that's alright. Feel free to edit the BZ >> title; I might not have captured the use case exactly. >> >> Thanks! >> Laszlo >> >> >>> Thanks! >>> Jeff >>> >>> -----Original Message----- >>> From: Laszlo Ersek [mailto:[email protected]] >>> Sent: Thursday, November 24, 2016 12:05 AM >>> To: Fan, Jeff; edk2-devel-01 >>> Cc: Igor Mammedov >>> Subject: Re: [PATCH 3/4] UefiCpuPkg/MpInitLib: allow platforms to provide a >>> known CPU count upfront >>> >>> On 11/23/16 06:36, Fan, Jeff wrote: >>>> Laszlo, >>>> >>>> I ever submitted one bugzilla for such request at >>>> https://bugzilla.tianocore.org/show_bug.cgi?id=116 >>> >>> Huh, I didn't know about that. :) >>> >>>> My point is not to add new PCD and just to use existing PCD >>>> PcdCpuMaxLogicalProcessorNumber that supports dynamic type. >>>> >>>> Platform Peim could update it is platform pei module before memory ready. >>>> >>>> MpInitLib just exits from wait loop once the discovered processors >>>> number reaches the PcdCpuMaxLogicalProcessorNumber. >>>> >>>> Does it meet your requirement? >>> >>> This was the first idea I had as well, yes. However, I considered the >>> following case: >>> >>> - QEMU is started (and the guest is booted) with N online processors and M >>> > N *possible* processors. >>> >>> - During OS runtime, the user hotplugs one or more additional processors, >>> so that the number of currently online processors is now larger than N. >>> >>> - The user suspends and resumes (S3) the virtual machine. >>> >>> - During S3 resume, QEMU will report the increased number of boot >>> processors. (At S3 resume, QEMU specifically refreshes the fw_cfg item that >>> returns this value to the firmware, from the increased number of >>> VCPUs.) >>> >>> - During S3 resume, we cannot modify PcdCpuMaxLogicalProcessorNumber any >>> longer, because the UefiCpuPkg modules that consume the PCD have already >>> allocated their data structures using the first (lower) value. Those >>> allocations cannot be resized / extended during S3 resume. >>> >>> So the idea is, set PcdCpuMaxLogicalProcessorNumber statically to the >>> number of the expected maximum VCPU count, which will ensure the proper >>> allocations during first boot. Then allow PcdCpuKnownLogicalProcessorNumber >>> to change -- hot-unplug is also possible -- from normal boot to S3 resume. >>> >>> (The concept of "expected maximum" is not specific to VCPU hotplug in QEMU, >>> it applies to memory (DIMM) hotplug and memory ballooning as well.) >>> >>> Of course, I don't know (or expect) that the UefiCpuPkg modules fully >>> support this use case right now; it's just that I didn't want to >>> *prevent* this use case. So I figured I'd preserve the original role of >>> PcdCpuMaxLogicalProcessorNumber, and introduce a more dynamic value for the >>> "current boot VCPU count". >>> >>> Do you agree that it makes sense to keep these quantities separate? >>> >>> If you think we should just set PcdCpuMaxLogicalProcessorNumber dynamically >>> at this point, and introduce no new PCD for now, I can do that too. I just >>> wanted to make sure that we discuss VCPU hot-plug / hot-unplug and S3 >>> resume first. >>> >>> Thanks! >>> Laszlo >>> >>>> >>>> Thanks! >>>> Jeff >>>> >>>> -----Original Message----- >>>> From: Laszlo Ersek [mailto:[email protected]] >>>> Sent: Wednesday, November 23, 2016 4:26 AM >>>> To: edk2-devel-01 >>>> Cc: Igor Mammedov; Fan, Jeff >>>> Subject: [PATCH 3/4] UefiCpuPkg/MpInitLib: allow platforms to provide >>>> a known CPU count upfront >>>> >>>> On QEMU/KVM, the VCPU topology for a guest is specified dynamically. It >>>> can be a low number or a high number. >>>> >>>> Waiting for PcdCpuApInitTimeOutInMicroSeconds during the initial AP >>>> collection is impractical, because in a VM, the time needed for an AP to >>>> wake up can vary widely: >>>> >>>> - if the APs report back quickly, then we could be wasting time, >>>> >>>> - if the APs report back late (due to scheduling artifacts or VCPU >>>> over-subscription on the virtualization host), then the timeout can >>>> elapse before all APs increment CpuMpData->CpuCount in >>>> ApWakeupFunction(). >>>> >>>> Trying to set PcdCpuApInitTimeOutInMicroSeconds dynamically is also >>>> impractical, as scheduling artifacts on the KVM host may delay AP threads >>>> arbitrarily. >>>> >>>> Instead, allow OVMF (and other platforms) to tell MpInitLib the number of >>>> boot-time CPUs in advance. >>>> >>>> Cc: Igor Mammedov <[email protected]> >>>> Cc: Jeff Fan <[email protected]> >>>> Contributed-under: TianoCore Contribution Agreement 1.0 >>>> Signed-off-by: Laszlo Ersek <[email protected]> >>>> --- >>>> UefiCpuPkg/UefiCpuPkg.dec | 11 +++++++++++ >>>> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 1 + >>>> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 ++-- >>>> UefiCpuPkg/Library/MpInitLib/MpLib.c | 16 ++++++++++++---- >>>> 4 files changed, 26 insertions(+), 6 deletions(-) >>>> >>>> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec >>>> index ca560398bbef..35903c4386e4 100644 >>>> --- a/UefiCpuPkg/UefiCpuPkg.dec >>>> +++ b/UefiCpuPkg/UefiCpuPkg.dec >>>> @@ -225,5 +225,16 @@ [PcdsDynamic, PcdsDynamicEx] >>>> # @ValidList 0x80000001 | 0 >>>> >>>> gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress|0x0|UINT64|0x600000 >>>> 11 >>>> >>>> + ## On platforms where the number of boot-time CPUs can be >>>> + dynamically # retrieved from a platform-specific information >>>> + source, the BSP does not # have to wait for >>>> + PcdCpuApInitTimeOutInMicroSeconds in order to detect all # APs for >>>> + the first time. On such platforms, this PCD specifies the number # >>>> + of CPUs available at boot. If the platform doesn't support this >>>> + feature, # this PCD should be set to 0. The platform is >>>> + responsible for ensuring that # this PCD is never set to a value >>>> larger than # PcdCpuMaxLogicalProcessorNumber. >>>> + # @Prompt Known number of CPUs available at boot. >>>> + >>>> + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownLogicalProcessorNumber|0|UINT32 >>>> + |0 >>>> + x60000012 >>>> + >>>> [UserExtensions.TianoCore."ExtraFiles"] >>>> UefiCpuPkgExtra.uni >>>> diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf >>>> b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf >>>> index 11b230174ec8..dc18eaf6152d 100644 >>>> --- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf >>>> +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf >>>> @@ -61,6 +61,7 @@ [Guids] >>>> >>>> [Pcd] >>>> gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## >>>> CONSUMES >>>> + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownLogicalProcessorNumber ## >>>> SOMETIMES_CONSUMES >>>> gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## >>>> SOMETIMES_CONSUMES >>>> gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## >>>> CONSUMES >>>> gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## >>>> CONSUMES >>>> diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf >>>> b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf >>>> index 0c6873da79db..2bcfa70ae7e5 100644 >>>> --- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf >>>> +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf >>>> @@ -61,10 +61,10 @@ [Ppis] >>>> >>>> [Pcd] >>>> gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## >>>> CONSUMES >>>> - gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## >>>> CONSUMES >>>> + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownLogicalProcessorNumber ## >>>> CONSUMES >>>> + gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## >>>> SOMETIMES_CONSUMES >>>> gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## >>>> CONSUMES >>>> gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## >>>> CONSUMES >>>> gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## >>>> CONSUMES >>>> gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## >>>> CONSUMES >>>> gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## >>>> SOMETIMES_CONSUMES >>>> - >>>> diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c >>>> b/UefiCpuPkg/Library/MpInitLib/MpLib.c >>>> index 15dbfa1e7d6c..f7dfbd5bad13 100644 >>>> --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c >>>> +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c >>>> @@ -707,6 +707,7 @@ WakeUpAP ( >>>> CPU_AP_DATA *CpuData; >>>> BOOLEAN ResetVectorRequired; >>>> CPU_INFO_IN_HOB *CpuInfoInHob; >>>> + UINT32 KnownProcessorCount; >>>> >>>> CpuMpData->FinishedCount = 0; >>>> ResetVectorRequired = FALSE; >>>> @@ -745,10 +746,17 @@ WakeUpAP ( >>>> SendInitSipiSipiAllExcludingSelf ((UINT32) >>>> ExchangeInfo->BufferStart); >>>> } >>>> if (CpuMpData->InitFlag == ApInitConfig) { >>>> - // >>>> - // Wait for all potential APs waken up in one specified period >>>> - // >>>> - MicroSecondDelay (PcdGet32(PcdCpuApInitTimeOutInMicroSeconds)); >>>> + KnownProcessorCount = PcdGet32 (PcdCpuKnownLogicalProcessorNumber); >>>> + if (KnownProcessorCount > 0) { >>>> + while (CpuMpData->FinishedCount < (KnownProcessorCount - 1)) { >>>> + CpuPause (); >>>> + } >>>> + } else { >>>> + // >>>> + // Wait for all potential APs waken up in one specified period >>>> + // >>>> + MicroSecondDelay (PcdGet32(PcdCpuApInitTimeOutInMicroSeconds)); >>>> + } >>>> } else { >>>> // >>>> // Wait all APs waken up if this is not the 1st broadcast of >>>> SIPI >>>> -- >>>> 2.9.2 >>>> >>>> >>> >> > _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

