From nobody Wed Feb 01 12:27:22 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4P6LlZ5CF3z3c5bX; Wed, 1 Feb 2023 12:27:22 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4P6LlZ4fmSz45Q1; Wed, 1 Feb 2023 12:27:22 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1675254442; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=VwxxHwdrIuwVNXmqBeWxOwUqti5PDcB7jWeU93EQYsk=; b=DkzLvWUJOK4rqpRaNsdZhkGVllGYQNCgIgu6gSuoqZXUm0KHpZSKNt4DcDNloCpFttL3jb p5ShUVocEcfjYU9yafs2SJuWaP48FiXsXoM3IGn14t7pID7JTPoBNiHfUFVEoqyqf6qQqk f5LP2rfa9QHy7rkiL28gBYGFVfNcIgK1m3jxgG/YFqDxG8KA/yIfYQXQx95EuCrPuq31w1 CG6qmjYnXYcrjoZGy4J6ujPu+gMeRpRrl4mdlVzLcvpB2Z9tAs7wobEYQRov/jZ+qjkvf4 DxDEriuMXvPHOHsp8CXBnSEQIIqcjEA59uzc4ftx4nhe4Uvob1w2kXz+tmnZ+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1675254442; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=VwxxHwdrIuwVNXmqBeWxOwUqti5PDcB7jWeU93EQYsk=; b=LRTIUjF2hw2p0lvlDX499Mj+Qq5D3BwCXlsfA3a50XSWz2zkuv+K2ARp3r2gjrnJpbC8Ra lBduEU+MMo+kk3FY527QFJeq+sUlE3rujllIunOj8eGQgWaysEBu7pm98WwydXUrgUlB2V Y48R/O9k/7KcnzVYApuuqULNz/3yjBDY/YcYVJoyHUebqhmW7GpXXTPneo9IypGtEKeOpL N57lRG9JcKnZLZ7hL/35VNAHMPGyWd+vrOZHXNLroIpnklOY1lQUn5kXqaAEFXxPNXylMU fSv4QIwSJLkcAswIu+LxHrqtuARKxxR7s3ebLDyGRLvkDCjMG9g/0e6bXpSo7Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1675254442; a=rsa-sha256; cv=none; b=ZSQsnKqkShG2NwADm7geO8PcEEkuTnNXFUR2Yz+Ijsc5cviZTfWRYVs5FoOAMyNbVvFBnH 0gRoOYEZO+KSUUyjNX9rGJAIV3Ytqnuq7mzKlSHxlQPuGp0rP5P1sFD5cBj34dEJDH0jtD q3vOk8PWoFhU0Ny4ZgALvTiT6T05tpt6UpANelEJe3LnfN7al2v+xHhumBsn8+u901dDfS 7ZPrBYuqRtJGrf0O4LxUadqpmyATfSFWH7G2mfzJlbl8h/ATvMDFB4xT1TW77dEdMBm5mq BqxsTaVqpFTbrHw6U7A6zLeCM+oklGMtiZ/aFNRRCYnQuzTwu/eayv8SVjn/nQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4P6LlZ3jsvzDj2; Wed, 1 Feb 2023 12:27:22 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 311CRMD2017682; Wed, 1 Feb 2023 12:27:22 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 311CRMjk017681; Wed, 1 Feb 2023 12:27:22 GMT (envelope-from git) Date: Wed, 1 Feb 2023 12:27:22 GMT Message-Id: <202302011227.311CRMjk017681@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: =?utf-8?Q?Corvin=20K=C3=B6hne?= Subject: git: 892feec2211d - main - vmm: avoid spurious rendezvous List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: corvink X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 892feec2211d0dbd58252a34d78dbcb2d5dd7593 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by corvink: URL: https://cgit.FreeBSD.org/src/commit/?id=892feec2211d0dbd58252a34d78dbcb2d5dd7593 commit 892feec2211d0dbd58252a34d78dbcb2d5dd7593 Author: Corvin Köhne AuthorDate: 2022-11-15 10:53:49 +0000 Commit: Corvin Köhne CommitDate: 2023-02-01 11:36:36 +0000 vmm: avoid spurious rendezvous A vcpu only checks if a rendezvous is in progress or not to decide if it should handle a rendezvous. This could lead to spurios rendezvous where a vcpu tries a handle a rendezvous it isn't part of. This situation is properly handled by vm_handle_rendezvous but it could potentially degrade the performance. Avoid that by an early check if the vcpu is part of the rendezvous or not. At the moment, rendezvous are only used to spin up application processors and to send ioapic interrupts. Spinning up application processors is done in the guest boot phase by sending INIT SIPI sequences to single vcpus. This is known to cause spurious rendezvous and only occurs in the boot phase. Sending ioapic interrupts is rare because modern guest will use msi and the rendezvous is always send to all vcpus. Reviewed by: jhb MFC after: 1 week Sponsored by: Beckhoff Automation GmbH & Co. KG Differential Revision: https://reviews.freebsd.org/D37390 --- sys/amd64/include/vmm.h | 14 ++++++++++---- sys/amd64/vmm/amd/svm.c | 2 +- sys/amd64/vmm/intel/vmx.c | 2 +- sys/amd64/vmm/vmm.c | 3 ++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h index 67730cc22980..bd6510b92527 100644 --- a/sys/amd64/include/vmm.h +++ b/sys/amd64/include/vmm.h @@ -159,7 +159,7 @@ struct pmap; enum snapshot_req; struct vm_eventinfo { - void *rptr; /* rendezvous cookie */ + cpuset_t *rptr; /* rendezvous cookie */ int *sptr; /* suspend cookie */ int *iptr; /* reqidle cookie */ }; @@ -331,10 +331,16 @@ void vm_await_start(struct vm *vm, const cpuset_t *waiting); #endif /* _SYS__CPUSET_H_ */ static __inline int -vcpu_rendezvous_pending(struct vm_eventinfo *info) +vcpu_rendezvous_pending(struct vcpu *vcpu, struct vm_eventinfo *info) { - - return (*((uintptr_t *)(info->rptr)) != 0); + /* + * This check isn't done with atomic operations or under a lock because + * there's no need to. If the vcpuid bit is set, the vcpu is part of a + * rendezvous and the bit won't be cleared until the vcpu enters the + * rendezvous. On rendezvous exit, the cpuset is cleared and the vcpu + * will see an empty cpuset. So, the races are harmless. + */ + return (CPU_ISSET(vcpu_vcpuid(vcpu), info->rptr)); } static __inline int diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c index 2448501401e3..ee1154ef85b6 100644 --- a/sys/amd64/vmm/amd/svm.c +++ b/sys/amd64/vmm/amd/svm.c @@ -2053,7 +2053,7 @@ svm_run(void *vcpui, register_t rip, pmap_t pmap, struct vm_eventinfo *evinfo) break; } - if (vcpu_rendezvous_pending(evinfo)) { + if (vcpu_rendezvous_pending(vcpu->vcpu, evinfo)) { enable_gintr(); vm_exit_rendezvous(vcpu->vcpu, state->rip); break; diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index 4b65e254cc91..fa94c707001c 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -3071,7 +3071,7 @@ vmx_run(void *vcpui, register_t rip, pmap_t pmap, struct vm_eventinfo *evinfo) break; } - if (vcpu_rendezvous_pending(evinfo)) { + if (vcpu_rendezvous_pending(vcpu->vcpu, evinfo)) { enable_intr(); vm_exit_rendezvous(vcpu->vcpu, rip); break; diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index 24f97a9244f0..7327bf6f40be 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -1438,6 +1438,7 @@ vm_handle_rendezvous(struct vcpu *vcpu) if (CPU_CMP(&vm->rendezvous_req_cpus, &vm->rendezvous_done_cpus) == 0) { VMM_CTR0(vcpu, "Rendezvous completed"); + CPU_ZERO(&vm->rendezvous_req_cpus); vm->rendezvous_func = NULL; wakeup(&vm->rendezvous_func); break; @@ -1858,7 +1859,7 @@ vm_run(struct vcpu *vcpu, struct vm_exit *vme_user) pmap = vmspace_pmap(vm->vmspace); vme = &vcpu->exitinfo; - evinfo.rptr = &vm->rendezvous_func; + evinfo.rptr = &vm->rendezvous_req_cpus; evinfo.sptr = &vm->suspend; evinfo.iptr = &vcpu->reqidle; restart: