From nobody Wed Feb 08 10:40:22 2023 X-Original-To: dev-commits-src-branches@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 4PBc2t5TLRz3n1f0; Wed, 8 Feb 2023 10:40: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 4PBc2t51jyz436r; Wed, 8 Feb 2023 10:40:22 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1675852822; 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=O0c4NlmJt0lF6BUYtUUQA/sK0Zd2/b6Veivk0pcmPNE=; b=y4HWdbywOyC3XYMFHke0VeMAnSWyh/6xGuKYJEamFy4w31z7dLdYaiv1n9S4EtisJQ2N0o Z8TM4Bpi0Mgud4SJ80jCphVa5qMds4ZLXx1hmKhmlgt6jEMZtbbYpjge+kdkX1/fAU407P /NFSj+pgWvAxjstjLgDXeXTNCIfOR8G2HKOJxq0PvSuAwSmfDrMg8+rPKNB43KiimqLL9W iAzwIHlPS7sCXy5RQyvfSWg0tKihy5cTS417oQMzt1QKEAgHtKprAdCra3Je5GnEOZwL7L 1nL+nRSsfqI+V//zb5Durf9f0MYoS5KNwKhq/v+DenB57J1tLSqEkSVzJBwnDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1675852822; 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=O0c4NlmJt0lF6BUYtUUQA/sK0Zd2/b6Veivk0pcmPNE=; b=skhO57M8R5jdHAv8Hht6k7GQYti7ivvyTHuP6KflUkgAv02mey62GOQk6k2GMhXnRjuy6q yuYaSP0iYhC8vA3j0dhaD4ZcEj72CG7zCCSR/6BPIMvY8ojUCe9THAoFx7Rrqd7YMKSUCZ 66MC2T3fDeZ8Ru7kDHYc3Pa6itsKyvCjKaMAdwO05RJZLbzsYRp0tO5NI2Do2wNlTEWZ5F SB7jHxqjGSY6CIwNrQAMsdU1fbE14rexMdFoya5BZRsPJSp1uP21lTeB9xHdUbdIL4j5CA stTtCUe6DniNMKG4kaYa02biZmRV9EBsVdUHcx9B8X2j8XlvlIAa3l9q0c+0Ng== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1675852822; a=rsa-sha256; cv=none; b=I10L2w6DgCCeSvDZ3SbwqsI8mx258moAGCQPizUUAcN91vdcfZwGAo3wXhNI2RN1sBVVCM m4c6E1ffgpNx5zX+VcX/ekcB86qRAksLd6g8tNL7fyBOY/3mS382J8pUAA5EXPBdmK5S48 /oIcGaKzE0ra0Ry5Uz387fxY0A+MdSQD7HylwrfBdCuiM3HgXAOHT7mWZ4WYbwrBKvepKp w2JpBIYe+sHPodBmzFTDZjDL8WFxc4KOIuqP28EX0vtWEpfoIht+wct40SK+iEjpJXZilv TIcJHbKxcx0cdFiq4tvoxA36TfFEwIY4E8XgnXW012nC9Vq+WcYwyUncrsdR1g== 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 4PBc2t444rztdY; Wed, 8 Feb 2023 10:40: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 318AeMPM075550; Wed, 8 Feb 2023 10:40:22 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 318AeMVU075549; Wed, 8 Feb 2023 10:40:22 GMT (envelope-from git) Date: Wed, 8 Feb 2023 10:40:22 GMT Message-Id: <202302081040.318AeMVU075549@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: =?utf-8?Q?Corvin=20K=C3=B6hne?= Subject: git: 7148611e4f56 - stable/13 - vmm: avoid spurious rendezvous List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@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/stable/13 X-Git-Reftype: branch X-Git-Commit: 7148611e4f560f375d4b92fdeb9451a792dc73fc Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by corvink: URL: https://cgit.FreeBSD.org/src/commit/?id=7148611e4f560f375d4b92fdeb9451a792dc73fc commit 7148611e4f560f375d4b92fdeb9451a792dc73fc Author: Corvin Köhne AuthorDate: 2022-11-15 10:53:49 +0000 Commit: Corvin Köhne CommitDate: 2023-02-08 09:28:47 +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 (cherry picked from commit 892feec2211d0dbd58252a34d78dbcb2d5dd7593) --- 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 15f946d4f120..cb883bb0e143 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 f0ee159dcbb9..123d35a983c0 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: