Received: by 10.223.164.202 with SMTP id h10csp81848wrb; Tue, 14 Nov 2017 18:03:02 -0800 (PST) X-Google-Smtp-Source: AGs4zMahwJRa5iI5qRttGz8XB0y4h/JlBL2dbA7deGMtPzexmMsqactBheyJzMA/sZRlO1lfCYQ0 X-Received: by 10.98.157.67 with SMTP id i64mr15828038pfd.40.1510711382430; Tue, 14 Nov 2017 18:03:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510711382; cv=none; d=google.com; s=arc-20160816; b=eddYapoFP78oFGaF5cIcD01JokC/+is5Fkd7RTrYteoPRdD0AM4jpiXoMF8VvRB3lm CaghvrBFY9UuBFt41YCyXfsTTKB1S9Kp8IhOrQS+yQmgb94NJpQBQCFofN7SA9VDf3Py 829+LEcJMnL9+Z79TcTpWs0YrAHcFl9Gm2W/aVyaDNzxjVjoxsAPZNqpnRhr577W4+fx MlgtmkVq/a5gDRTAYLSi1p4KE0Z7aKn6ZkI8KPF5PeZijYe4sTK4fzwa1yaRX1M0WNCs N55eQYG2u1vLiBneEv7rZGt54sk0NtCbmlJGrWGg4556IuxpI30AThAVISn5e+Ikxl6y qrOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=0rR9vdiFCY4PzvqVQDMa50NMtrPQEkfIop3LyhDcgnY=; b=mXHCMb3dvBZY10fr48aoK8hYel3Yl7fhJh9lyxMqCaGwZAUIPPkFdu/i0hsRsnxQa/ 7SzPEFLV3PMPVqt1WjJee9241mJ8Aj4TXamPLI2739W39pmsbJelWfnG0JAtwsTy6WMr AMw8/7oIzj5by0Rk3iwhn6so2zBSpb7IogXWgiu+g45ysq61WzGoTb13nHecz5aTWZpo WYX+mdo6EvE5asRlWtwT/wXUgqf2dJQzmOHbYni/NoIKGCV/3GcBy+i3hdsKplsBhqZ+ gh9ATjkpRhqMg0KJiqE2yRBzA5lRPGNw40jFS5Xf38kf+ySzl+ltgeSH/UXOV/jwQPSM fNvQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=g01Qs7KF; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ay8si16624466plb.436.2017.11.14.18.02.40; Tue, 14 Nov 2017 18:03:02 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=g01Qs7KF; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756850AbdKOAsA (ORCPT + 87 others); Tue, 14 Nov 2017 19:48:00 -0500 Received: from mail-ot0-f193.google.com ([74.125.82.193]:53459 "EHLO mail-ot0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754866AbdKOArw (ORCPT ); Tue, 14 Nov 2017 19:47:52 -0500 Received: by mail-ot0-f193.google.com with SMTP id 105so9185514oth.10; Tue, 14 Nov 2017 16:47:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=0rR9vdiFCY4PzvqVQDMa50NMtrPQEkfIop3LyhDcgnY=; b=g01Qs7KFEwzNOR4LTjBNgO1p1Pui+ZJCvX46zV5zW3dazkIcm0Ka4Gx/DuEuXY7Q3g 9zxutBx5YEoWafPtV4Zkx77RrLBJYtk+jrN5kEtzyvS0ep8GxmvxCq9GfIHyB8pUuCob 84VOAreqiFqDSdSrpee9nZkcJxvMs4FpYdITi3/NrCf+/MM38VNIYO+ao5P+hztZfXS6 mCbQW+nzSaMPNQ3+ttyrq82FQ017lYCqfOMZ7kmsm7a0NrlsbcAzytk2i1pqwfWSEHwp f+gwNWgQn6ZgqANRfkLV3qjYvx1nczYxEZf/W1Brdn7O1wqwT2JYyy7TxK2pfSGRxzV2 N+Mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=0rR9vdiFCY4PzvqVQDMa50NMtrPQEkfIop3LyhDcgnY=; b=hHGy8uPJWiLYi5YJnuMwuCBE1Tmi0b8+RzvV3OKzmBtLiYzH2+dM2zUbSCQLOKhGVl 1DM+eUwYHrysEdgmLcEZNO/Z57YdX+noLl30OaNHu6CfxcxoP59f7e88rECNcEsNx+7s MiS8czBzQbNreNiGXtqwj1IiKjUe+umiuRZd3vklX6omb7GiexHKbNRpONNOWFnf/qme aeKvx0MxNf2W+DE1q2WHcSQQ8dVvB5wdVXVrnQD47wB9hQMNjj7Athmg3jxDFmTdfZxk hLjWujy6BRv9u1vf1iRf169IhOr5h1TaE3T5f2OyfzUQeVUiKmqwCn5zsj5lwoOzlBj1 Mnww== X-Gm-Message-State: AJaThX6b2cdfdbHH/DdHbWzvJI1l9yKx4NqLcgq1WZZf8gLJWajOjI66 U8ePAbmvteU9J3vccCA5/iC7acliOKXJFK/snOI= X-Received: by 10.157.45.80 with SMTP id v74mr7289671ota.62.1510706872135; Tue, 14 Nov 2017 16:47:52 -0800 (PST) MIME-Version: 1.0 Received: by 10.74.53.27 with HTTP; Tue, 14 Nov 2017 16:47:51 -0800 (PST) In-Reply-To: <20171114215424.32214-2-riel@redhat.com> References: <20171114215424.32214-1-riel@redhat.com> <20171114215424.32214-2-riel@redhat.com> From: Wanpeng Li Date: Wed, 15 Nov 2017 08:47:51 +0800 Message-ID: Subject: Re: [PATCH 1/2] x86,kvm: move qemu/guest FPU switching out to vcpu_run To: Rik van Riel Cc: Paolo Bonzini , kvm , "linux-kernel@vger.kernel.org" , David Hildenbrand , Christian Borntraeger , Thomas Gleixner , Radim Krcmar Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 2017-11-15 5:54 GMT+08:00 : > From: Rik van Riel > > Currently, every time a VCPU is scheduled out, the host kernel will > first save the guest FPU/xstate context, then load the qemu userspace > FPU context, only to then immediately save the qemu userspace FPU > context back to memory. When scheduling in a VCPU, the same extraneous > FPU loads and saves are done. > > This could be avoided by moving from a model where the guest FPU is > loaded and stored with preemption disabled, to a model where the > qemu userspace FPU is swapped out for the guest FPU context for > the duration of the KVM_RUN ioctl. What will happen if CONFIG_PREEMPT is enabled? Regards, Wanpeng Li > > This is done under the VCPU mutex, which is also taken when other > tasks inspect the VCPU FPU context, so the code should already be > safe for this change. That should come as no surprise, given that > s390 already has this optimization. > > No performance changes were detected in quick ping-pong tests on > my 4 socket system, which is expected since an FPU+xstate load is > on the order of 0.1us, while ping-ponging between CPUs is on the > order of 20us, and somewhat noisy. > > There may be other tests where performance changes are noticeable. > > Signed-off-by: Rik van Riel > Suggested-by: Christian Borntraeger > --- > arch/x86/include/asm/kvm_host.h | 13 +++++++++++++ > arch/x86/kvm/x86.c | 34 +++++++++++++--------------------- > include/linux/kvm_host.h | 2 +- > 3 files changed, 27 insertions(+), 22 deletions(-) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index 9d7d856b2d89..ffe54958491f 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -536,7 +536,20 @@ struct kvm_vcpu_arch { > struct kvm_mmu_memory_cache mmu_page_cache; > struct kvm_mmu_memory_cache mmu_page_header_cache; > > + /* > + * QEMU userspace and the guest each have their own FPU state. > + * In vcpu_run, we switch between the user and guest FPU contexts. > + * While running a VCPU, the VCPU thread will have the guest FPU > + * context. > + * > + * Note that while the PKRU state lives inside the fpu registers, > + * it is switched out separately at VMENTER and VMEXIT time. The > + * "guest_fpu" state here contains the guest FPU context, with the > + * host PRKU bits. > + */ > + struct fpu user_fpu; > struct fpu guest_fpu; > + > u64 xcr0; > u64 guest_supported_xcr0; > u32 guest_xstate_size; > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 03869eb7fcd6..aad5181ed4e9 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -2917,7 +2917,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) > srcu_read_unlock(&vcpu->kvm->srcu, idx); > pagefault_enable(); > kvm_x86_ops->vcpu_put(vcpu); > - kvm_put_guest_fpu(vcpu); > vcpu->arch.last_host_tsc = rdtsc(); > } > > @@ -5228,13 +5227,10 @@ static void emulator_halt(struct x86_emulate_ctxt *ctxt) > > static void emulator_get_fpu(struct x86_emulate_ctxt *ctxt) > { > - preempt_disable(); > - kvm_load_guest_fpu(emul_to_vcpu(ctxt)); > } > > static void emulator_put_fpu(struct x86_emulate_ctxt *ctxt) > { > - preempt_enable(); > } > > static int emulator_intercept(struct x86_emulate_ctxt *ctxt, > @@ -6908,7 +6904,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) > preempt_disable(); > > kvm_x86_ops->prepare_guest_switch(vcpu); > - kvm_load_guest_fpu(vcpu); > > /* > * Disable IRQs before setting IN_GUEST_MODE. Posted interrupt > @@ -7255,12 +7250,14 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) > } > } > > + kvm_load_guest_fpu(vcpu); > + > if (unlikely(vcpu->arch.complete_userspace_io)) { > int (*cui)(struct kvm_vcpu *) = vcpu->arch.complete_userspace_io; > vcpu->arch.complete_userspace_io = NULL; > r = cui(vcpu); > if (r <= 0) > - goto out; > + goto out_fpu; > } else > WARN_ON(vcpu->arch.pio.count || vcpu->mmio_needed); > > @@ -7269,6 +7266,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) > else > r = vcpu_run(vcpu); > > +out_fpu: > + kvm_put_guest_fpu(vcpu); > out: > post_kvm_run_save(vcpu); > if (vcpu->sigset_active) > @@ -7663,32 +7662,25 @@ static void fx_init(struct kvm_vcpu *vcpu) > vcpu->arch.cr0 |= X86_CR0_ET; > } > > +/* Swap (qemu) user FPU context for the guest FPU context. */ > void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) > { > - if (vcpu->guest_fpu_loaded) > - return; > - > - /* > - * Restore all possible states in the guest, > - * and assume host would use all available bits. > - * Guest xcr0 would be loaded later. > - */ > - vcpu->guest_fpu_loaded = 1; > - __kernel_fpu_begin(); > + preempt_disable(); > + copy_fpregs_to_fpstate(&vcpu->arch.user_fpu); > /* PKRU is separately restored in kvm_x86_ops->run. */ > __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state, > ~XFEATURE_MASK_PKRU); > + preempt_enable(); > trace_kvm_fpu(1); > } > > +/* When vcpu_run ends, restore user space FPU context. */ > void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) > { > - if (!vcpu->guest_fpu_loaded) > - return; > - > - vcpu->guest_fpu_loaded = 0; > + preempt_disable(); > copy_fpregs_to_fpstate(&vcpu->arch.guest_fpu); > - __kernel_fpu_end(); > + copy_kernel_to_fpregs(&vcpu->arch.user_fpu.state); > + preempt_enable(); > ++vcpu->stat.fpu_reload; > trace_kvm_fpu(0); > } > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > index 6882538eda32..354608487b8d 100644 > --- a/include/linux/kvm_host.h > +++ b/include/linux/kvm_host.h > @@ -232,7 +232,7 @@ struct kvm_vcpu { > struct mutex mutex; > struct kvm_run *run; > > - int guest_fpu_loaded, guest_xcr0_loaded; > + int guest_xcr0_loaded; > struct swait_queue_head wq; > struct pid __rcu *pid; > int sigset_active; > -- > 2.9.4 > From 1584086834170200521@xxx Tue Nov 14 23:42:08 +0000 2017 X-GM-THRID: 1584017174910331026 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread