From patchwork Tue Dec 15 04:08:31 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zachary Amsden X-Patchwork-Id: 67475 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nBF4QSLo016846 for ; Tue, 15 Dec 2009 04:26:31 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759240AbZLOEKm (ORCPT ); Mon, 14 Dec 2009 23:10:42 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1758078AbZLOEHR (ORCPT ); Mon, 14 Dec 2009 23:07:17 -0500 Received: from mx1.redhat.com ([209.132.183.28]:7021 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758537AbZLOEHA (ORCPT ); Mon, 14 Dec 2009 23:07:00 -0500 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id nBF46xg2023810 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 14 Dec 2009 23:06:59 -0500 Received: from localhost.localdomain (vpn-9-100.rdu.redhat.com [10.11.9.100]) by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id nBF46m8w031119; Mon, 14 Dec 2009 23:06:57 -0500 From: Zachary Amsden To: kvm@vger.kernel.org Cc: Zachary Amsden , Avi Kivity , Marcelo Tosatti , Joerg Roedel , linux-kernel@vger.kernel.org, Dor Laor Subject: [PATCH RFC: kvm tsc virtualization 04/20] Synchronize TSC when a new CPU comes up Date: Mon, 14 Dec 2009 18:08:31 -1000 Message-Id: <1260850127-9766-5-git-send-email-zamsden@redhat.com> In-Reply-To: <1260850127-9766-4-git-send-email-zamsden@redhat.com> References: <1260850127-9766-1-git-send-email-zamsden@redhat.com> <1260850127-9766-2-git-send-email-zamsden@redhat.com> <1260850127-9766-3-git-send-email-zamsden@redhat.com> <1260850127-9766-4-git-send-email-zamsden@redhat.com> Organization: Frobozz Magic Timekeeping Company X-Scanned-By: MIMEDefang 2.67 on 10.5.11.21 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 95e43b9..a599c78 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -729,6 +729,7 @@ static void kvm_set_time_scale(uint32_t tsc_khz, struct pvclock_vcpu_time_info * hv_clock->tsc_to_system_mul); } +DEFINE_SPINLOCK(kvm_tsc_lock); static DEFINE_PER_CPU(unsigned long, cpu_tsc_khz); static DEFINE_PER_CPU(unsigned long, cpu_tsc_multiplier); static DEFINE_PER_CPU(int, cpu_tsc_shift); @@ -921,6 +922,21 @@ static void kvm_sync_tsc(void *cpup) local_irq_restore(flags); } +static void kvm_do_sync_tsc(int cpu) +{ + spin_lock(&kvm_tsc_lock); + if (raw_smp_processor_id() != tsc_base_cpu) { + smp_call_function_single(tsc_base_cpu, kvm_sync_tsc, + (void *)&cpu, 0); + smp_call_function_single(cpu, kvm_sync_tsc, (void *)&cpu, 1); + } else { + smp_call_function_single(cpu, kvm_sync_tsc, (void *)&cpu, 0); + smp_call_function_single(tsc_base_cpu, kvm_sync_tsc, + (void *)&cpu, 1); + } + spin_unlock(&kvm_tsc_lock); +} + static void kvm_write_guest_time(struct kvm_vcpu *v) { struct timespec ts; @@ -1634,12 +1650,7 @@ out: void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { kvm_x86_ops->vcpu_load(vcpu, cpu); - if (unlikely(per_cpu(cpu_tsc_khz, cpu) == 0)) { - unsigned long khz = cpufreq_quick_get(cpu); - if (!khz) - khz = tsc_khz; - per_cpu(cpu_tsc_khz, cpu) = khz; - } + BUG_ON(per_cpu(cpu_tsc_khz, cpu) == 0); kvm_request_guest_time_update(vcpu); } @@ -3505,6 +3516,18 @@ static int kvm_x86_cpu_hotplug(struct notifier_block *notifier, val &= ~CPU_TASKS_FROZEN; switch (val) { + case CPU_DOWN_PREPARE: + if (cpu == tsc_base_cpu) { + int new_cpu; + spin_lock(&kvm_tsc_lock); + for_each_online_cpu(new_cpu) + if (new_cpu != tsc_base_cpu) + break; + tsc_base_cpu = new_cpu; + spin_unlock(&kvm_tsc_lock); + } + break; + case CPU_DYING: case CPU_UP_CANCELED: if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) @@ -3514,6 +3537,7 @@ static int kvm_x86_cpu_hotplug(struct notifier_block *notifier, case CPU_ONLINE: if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) per_cpu(cpu_tsc_khz, cpu) = cpufreq_quick_get(cpu); + kvm_do_sync_tsc(cpu); break; } return NOTIFY_OK; @@ -3548,11 +3572,8 @@ static void kvm_timer_init(void) per_cpu(cpu_tsc_shift, tsc_base_cpu) = 0; per_cpu(cpu_tsc_offset, tsc_base_cpu) = 0; for_each_online_cpu(cpu) - if (cpu != tsc_base_cpu) { - smp_call_function_single(cpu, kvm_sync_tsc, - (void *)&cpu, 0); - kvm_sync_tsc((void *)&cpu); - } + if (cpu != tsc_base_cpu) + kvm_do_sync_tsc(cpu); put_cpu(); }