Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753617AbdH2Ls7 (ORCPT ); Tue, 29 Aug 2017 07:48:59 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:36371 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753329AbdH2LrX (ORCPT ); Tue, 29 Aug 2017 07:47:23 -0400 From: Yang Zhang To: linux-kernel@vger.kernel.org Cc: kvm@vger.kernel.org, wanpeng.li@hotmail.com, mst@redhat.com, pbonzini@redhat.com, tglx@linutronix.de, rkrcmar@redhat.com, dmatlack@google.com, agraf@suse.de, peterz@infradead.org, linux-doc@vger.kernel.org, Yang Zhang , Quan Xu , Ingo Molnar , "H. Peter Anvin" , x86@kernel.org Subject: [RFC PATCH v2 2/7] KVM guest: register kvm_idle_poll for pv_idle_ops Date: Tue, 29 Aug 2017 11:46:36 +0000 Message-Id: <1504007201-12904-3-git-send-email-yang.zhang.wz@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1504007201-12904-1-git-send-email-yang.zhang.wz@gmail.com> References: <1504007201-12904-1-git-send-email-yang.zhang.wz@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2125 Lines: 74 Although smart idle poll has nothing to do with paravirt, it can not bring any benifit to native. So we only enable it when Linux runs as a KVM guest(it can extend to other hypervisor like Xen, HyperV and VMware). Introduce per-CPU variable poll_duration_ns to control the max poll time. Signed-off-by: Yang Zhang Signed-off-by: Quan Xu Cc: Paolo Bonzini Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: x86@kernel.org Cc: kvm@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- arch/x86/kernel/kvm.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index d04e30e..7d84a02 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -75,6 +75,7 @@ static int parse_no_kvmclock_vsyscall(char *arg) early_param("no-kvmclock-vsyscall", parse_no_kvmclock_vsyscall); +static DEFINE_PER_CPU(unsigned long, poll_duration_ns); static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64); static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64); static int has_steal_clock = 0; @@ -357,6 +358,29 @@ static void kvm_guest_cpu_init(void) kvm_register_steal_time(); } +static void kvm_idle_poll(void) +{ + unsigned long poll_duration = this_cpu_read(poll_duration_ns); + ktime_t start, cur, stop; + + start = cur = ktime_get(); + stop = ktime_add_ns(ktime_get(), poll_duration); + + do { + if (need_resched()) + break; + cur = ktime_get(); + } while (ktime_before(cur, stop)); +} + +static void kvm_guest_idle_init(void) +{ + if (!kvm_para_available()) + return; + + pv_idle_ops.poll = kvm_idle_poll; +} + static void kvm_pv_disable_apf(void) { if (!__this_cpu_read(apf_reason.enabled)) @@ -492,6 +516,8 @@ void __init kvm_guest_init(void) kvm_guest_cpu_init(); #endif + kvm_guest_idle_init(); + /* * Hard lockup detection is enabled by default. Disable it, as guests * can get false positives too easily, for example if the host is -- 1.8.3.1