From patchwork Thu Feb 16 16:04:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFkaW0gS3LEjW3DocWZ?= X-Patchwork-Id: 9577637 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3E2CD60209 for ; Thu, 16 Feb 2017 16:05:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 29AF828639 for ; Thu, 16 Feb 2017 16:05:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1EA542864A; Thu, 16 Feb 2017 16:05:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,HK_RANDOM_FROM, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C83BB28639 for ; Thu, 16 Feb 2017 16:05:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932651AbdBPQFP (ORCPT ); Thu, 16 Feb 2017 11:05:15 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47626 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932547AbdBPQFN (ORCPT ); Thu, 16 Feb 2017 11:05:13 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (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 5591A4DD4B; Thu, 16 Feb 2017 16:05:14 +0000 (UTC) Received: from potion (dhcp-1-208.brq.redhat.com [10.34.1.208]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id v1GG5Amw000974; Thu, 16 Feb 2017 11:05:11 -0500 Received: by potion (sSMTP sendmail emulation); Thu, 16 Feb 2017 17:05:09 +0100 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Andrew Jones , Marc Zyngier , Christian Borntraeger , Cornelia Huck , James Hogan , Paul Mackerras , Christoffer Dall Subject: [PATCH 4/5] KVM: add __kvm_request_needs_mb Date: Thu, 16 Feb 2017 17:04:48 +0100 Message-Id: <20170216160449.13094-5-rkrcmar@redhat.com> In-Reply-To: <20170216160449.13094-1-rkrcmar@redhat.com> References: <20170216160449.13094-1-rkrcmar@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 16 Feb 2017 16:05:14 +0000 (UTC) Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A macro to optimize requests that do not need a memory barrier because they have no dependencies. An architecture can implement a function that says which requests do not need memory barriers when handling them. Signed-off-by: Radim Krčmář --- include/linux/kvm_host.h | 41 +++++++++++++++++++++++++++++++++++++---- virt/kvm/kvm_main.c | 3 ++- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index d899473859d3..2cc438685af8 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1097,8 +1097,8 @@ static inline int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) * 2) remote request with no data (= kick) * 3) remote request with data (= kick + mb) * - * TODO: the API is inconsistent -- a request doesn't call kvm_vcpu_kick(), but - * forces smp_wmb() for all requests. + * TODO: the API does not distinguish local and remote requests -- remote + * should contain kvm_vcpu_kick(). */ static inline void __kvm_request_set(unsigned req, struct kvm_vcpu *vcpu) @@ -1106,6 +1106,37 @@ static inline void __kvm_request_set(unsigned req, struct kvm_vcpu *vcpu) set_bit(req, &vcpu->requests); } +/* + * __kvm_request_needs_mb is used to improve performance, so it should have no + * runtime overhead. + */ +static inline bool __kvm_request_needs_mb(int req) +{ + /* + * This barrier lets callers avoid the following pattern: + * if (__kvm_request_needs_mb(req)) + * ... + * else + * barrier(); + */ + barrier(); + + if (!__builtin_constant_p(req)) + return true; + +#ifdef kvm_arch_request_needs_mb + /* + * GCC optimizes pure kvm_arch_request_needs_mb() with a constant input + * into a contant, but __builtin_constant_p() is not so clever, so we + * cannot ensure that with: + * BUILD_BUG_ON(!__builtin_constant_p(kvm_arch_request_needs_mb(req))); + */ + return kvm_arch_request_needs_mb(req); +#else + return true; +#endif +} + static inline void kvm_request_set(unsigned req, struct kvm_vcpu *vcpu) { /* @@ -1113,7 +1144,8 @@ static inline void kvm_request_set(unsigned req, struct kvm_vcpu *vcpu) * kvm_request_test_and_clear's caller. * Paired with the smp_mb__after_atomic in kvm_request_test_and_clear. */ - smp_wmb(); + if (__kvm_request_needs_mb(req)) + smp_wmb(); __kvm_request_set(req, vcpu); } @@ -1137,7 +1169,8 @@ static inline bool kvm_request_test_and_clear(unsigned req, struct kvm_vcpu *vcp * kvm_request_test_and_clear's caller. * Paired with the smp_wmb in kvm_request_set. */ - smp_mb__after_atomic(); + if (__kvm_request_needs_mb(req)) + smp_mb__after_atomic(); return true; } else { return false; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 2250920ec965..ced3e4cb1df0 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -179,7 +179,8 @@ bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req) me = get_cpu(); /* Paired with the smp_mb__after_atomic in kvm_request_test_and_clear. */ - smp_wmb(); + if (__kvm_request_needs_mb(req)) + smp_wmb(); kvm_for_each_vcpu(i, vcpu, kvm) { __kvm_request_set(req, vcpu);