From patchwork Tue Nov 22 20:26:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laszlo Ersek X-Patchwork-Id: 83493 Delivered-To: patch@linaro.org Received: by 10.140.97.165 with SMTP id m34csp2299223qge; Tue, 22 Nov 2016 12:26:33 -0800 (PST) X-Received: by 10.99.102.69 with SMTP id a66mr46980555pgc.49.1479846393541; Tue, 22 Nov 2016 12:26:33 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id 70si29969591pga.188.2016.11.22.12.26.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 Nov 2016 12:26:33 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 2E89D81E5C; Tue, 22 Nov 2016 12:26:33 -0800 (PST) X-Original-To: edk2-devel@ml01.01.org Delivered-To: edk2-devel@ml01.01.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id DD28381E1F for ; Tue, 22 Nov 2016 12:26:31 -0800 (PST) Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 794313F20A; Tue, 22 Nov 2016 20:26:31 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-116-82.phx2.redhat.com [10.3.116.82]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uAMKQN4w021949; Tue, 22 Nov 2016 15:26:30 -0500 From: Laszlo Ersek To: edk2-devel-01 Date: Tue, 22 Nov 2016 21:26:18 +0100 Message-Id: <20161122202619.12594-4-lersek@redhat.com> In-Reply-To: <20161122202619.12594-1-lersek@redhat.com> References: <20161122202619.12594-1-lersek@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 22 Nov 2016 20:26:31 +0000 (UTC) Subject: [edk2] [PATCH 3/4] UefiCpuPkg/MpInitLib: allow platforms to provide a known CPU count upfront X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Igor Mammedov , Jeff Fan MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" 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 Cc: Jeff Fan Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek --- 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(-) -- 2.9.2 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel 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|0x60000011 + ## 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|0x60000012 + [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