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 <yang.zhang.wz@xxxxxxxxx> Signed-off-by: Quan Xu <quan.xu0@xxxxxxxxx> Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Cc: "H. Peter Anvin" <hpa@xxxxxxxxx> Cc: x86@xxxxxxxxxx Cc: kvm@xxxxxxxxxxxxxxx Cc: linux-kernel@xxxxxxxxxxxxxxx --- 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