From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6CD50158218 for ; Tue, 1 Oct 2024 23:23:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727825026; cv=none; b=e8NT5w+mQC9W+7sEdi4tT8gkAUa3g53mtybHeG1P+4Onn1HXwfcpdJmyHYGAd4lPBVm677EKlJDiADAploAScBmhzaQM1oe/+o3cCwKjAqUpkulK759+FQYNBoUdVkPfHfLVyeU+WvIyq2nGGd4XKwedohQQtAxtbHFh+dgsaPk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727825026; c=relaxed/simple; bh=PtsDxebjTQni2Zvds6FRpHilQV90bNhXcFOjDdLtf0U=; h=Date:Message-ID:From:To:Cc:Subject:In-Reply-To:References: MIME-Version:Content-Type; b=TLPeNdzf9m2J13dW/byJYGqcpN5kZuPAXtFUnvnjEpM5ja2gh6BHFWTkr3wjMJkNzKgj2p1BuDAVl5dohSE1syE/oI3nlYywc0BmrPiPGOm+i+1MoS5j8R0rJ3TrYUTydIheAKS3OQsXefyv6P12In/ZgGn2QdO7TicfMbYBH5c= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jTL/Ov/q; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jTL/Ov/q" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E649BC4CEC6; Tue, 1 Oct 2024 23:23:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727825025; bh=PtsDxebjTQni2Zvds6FRpHilQV90bNhXcFOjDdLtf0U=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=jTL/Ov/qjMXsppGH49XIZaJeYSfBsX4kuDNjyQxpRllwxi/QMAmCRJji3Z25Hez9U Re9yGxmy2rNrHNKrDpOAvzE/BnsG0LRpK/XTxMGbKIfRTjy0qqnZV1xadae0INFjVI oh49hWfCtg9HVyHWDALB4fIRzU8IsaRfO/QOeua0+EY7vxm7VAeeSU5U/piVNUrl5o gXlj5+crGQ/VUJdCNgT9GsmyfzOmd0pCTL+Dck/jowB/ROG64TyKEFCWIJfwc0cr6K qaELkvi8ENUZgpVp3UA+WGullrxsL3pB+vtywCn7WF8WqcRTLkQJ5oWdooQIbyV+BK XitNGbKWgRkBQ== Received: from sofa.misterjones.org ([185.219.108.64] helo=goblin-girl.misterjones.org) by disco-boy.misterjones.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1svmDX-00GuKI-KJ; Wed, 02 Oct 2024 00:23:43 +0100 Date: Wed, 02 Oct 2024 00:23:43 +0100 Message-ID: <86ed4z76gw.wl-maz@kernel.org> From: Marc Zyngier To: Oliver Upton Cc: kvmarm@lists.linux.dev, Joey Gouly , Suzuki K Poulose , Zenghui Yu Subject: Re: [PATCH 3/3] KVM: arm64: nv: Punt stage-2 recycling to a vCPU request In-Reply-To: <20241001001709.1303668-4-oliver.upton@linux.dev> References: <20241001001709.1303668-1-oliver.upton@linux.dev> <20241001001709.1303668-4-oliver.upton@linux.dev> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM-LB/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL-LB/10.8 EasyPG/1.0.0 Emacs/29.4 (aarch64-unknown-linux-gnu) MULE/6.0 (HANACHIRUSATO) Precedence: bulk X-Mailing-List: kvmarm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Content-Type: text/plain; charset=US-ASCII X-SA-Exim-Connect-IP: 185.219.108.64 X-SA-Exim-Rcpt-To: oliver.upton@linux.dev, kvmarm@lists.linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false On Tue, 01 Oct 2024 01:17:09 +0100, Oliver Upton wrote: > > Currently, when a nested MMU is repurposed for some other MMU context, > KVM unmaps everything during vcpu_load() while holding the MMU lock for > write. This is quite a performance bottleneck for large nested VMs, as > all vCPU scheduling will spin until the unmap completes. > > Start punting the MMU cleanup to a vCPU request, where it is then > possible to periodically release the MMU lock and CPU in the presence of > contention. To make that possible, take a pin on the hardware MMU while > unmapping it to guarantee the responsible vCPU finds the MMU on the next > vcpu_load(). > > Ensure that no vCPU winds up using a stale MMU by tracking the pending > unmap on the S2 MMU itself and requesting an unmap on every vCPU that > finds it. > > Signed-off-by: Oliver Upton > --- > arch/arm64/include/asm/kvm_host.h | 3 +++ > arch/arm64/include/asm/kvm_nested.h | 2 ++ > arch/arm64/kvm/arm.c | 2 ++ > arch/arm64/kvm/nested.c | 21 +++++++++++++++++++-- > 4 files changed, 26 insertions(+), 2 deletions(-) > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h > index 268f69196380..1d310292c623 100644 > --- a/arch/arm64/include/asm/kvm_host.h > +++ b/arch/arm64/include/asm/kvm_host.h > @@ -51,6 +51,7 @@ > #define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5) > #define KVM_REQ_SUSPEND KVM_ARCH_REQ(6) > #define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7) > +#define KVM_REQ_NESTED_S2_UNMAP KVM_ARCH_REQ(8) > > #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ > KVM_DIRTY_LOG_INITIALLY_SET) > @@ -216,6 +217,8 @@ struct kvm_s2_mmu { > * >0: Somebody is actively using this. > */ > atomic_t refcnt; > + > + bool pending_unmap; > }; > > struct kvm_arch_memory_slot { > diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h > index e74b90dcfac4..233e65522716 100644 > --- a/arch/arm64/include/asm/kvm_nested.h > +++ b/arch/arm64/include/asm/kvm_nested.h > @@ -78,6 +78,8 @@ extern void kvm_s2_mmu_iterate_by_vmid(struct kvm *kvm, u16 vmid, > extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu); > extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu); > > +extern void check_nested_vcpu_requests(struct kvm_vcpu *vcpu); > + > struct kvm_s2_trans { > phys_addr_t output; > unsigned long block_size; > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c > index 367f0d3d3194..ab7d387379a0 100644 > --- a/arch/arm64/kvm/arm.c > +++ b/arch/arm64/kvm/arm.c > @@ -1031,6 +1031,8 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu) > > if (kvm_dirty_ring_check_request(vcpu)) > return 0; > + > + check_nested_vcpu_requests(vcpu); > } > > return 1; > diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c > index 1ba211541290..749babdbda81 100644 > --- a/arch/arm64/kvm/nested.c > +++ b/arch/arm64/kvm/nested.c > @@ -632,9 +632,9 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu) > /* Set the scene for the next search */ > kvm->arch.nested_mmus_next = (i + 1) % kvm->arch.nested_mmus_size; > > - /* Clear the old state */ > + /* Make sure we don't forget to do the laundry */ > if (kvm_s2_mmu_valid(s2_mmu)) > - kvm_stage2_unmap_range(s2_mmu, 0, kvm_phys_size(s2_mmu), false); > + s2_mmu->pending_unmap = true; > > /* > * The virtual VMID (modulo CnP) will be used as a key when matching > @@ -649,6 +649,9 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu) > s2_mmu->nested_stage2_enabled = vcpu_read_sys_reg(vcpu, HCR_EL2) & HCR_VM; > > out: > + if (s2_mmu->pending_unmap) > + kvm_make_request(KVM_REQ_NESTED_S2_UNMAP, vcpu); > + > kvm_get_s2_mmu(s2_mmu); > return s2_mmu; > } > @@ -1186,3 +1189,17 @@ int kvm_init_nv_sysregs(struct kvm *kvm) > > return 0; > } > + > +void check_nested_vcpu_requests(struct kvm_vcpu *vcpu) > +{ > + if (kvm_check_request(KVM_REQ_NESTED_S2_UNMAP, vcpu)) { > + CLASS(vcpu_hw_mmu, mmu)(vcpu); I really think a small comment outlining *why* we need to elevate the refcount would help. This single line is what holds the whole thing together. Thanks, M. -- Without deviation from the norm, progress is not possible.