From patchwork Mon Jun 13 02:21:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Peng X-Patchwork-Id: 9171867 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 D650C6048C for ; Mon, 13 Jun 2016 02:32:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C8FD722473 for ; Mon, 13 Jun 2016 02:32:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BD85125EF7; Mon, 13 Jun 2016 02:32:34 +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,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1EB0622473 for ; Mon, 13 Jun 2016 02:32:33 +0000 (UTC) Received: from localhost ([::1]:53426 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCHg0-0007wN-8e for patchwork-qemu-devel@patchwork.kernel.org; Sun, 12 Jun 2016 22:32:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60182) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCHfi-0007w5-Qv for qemu-devel@nongnu.org; Sun, 12 Jun 2016 22:32:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bCHfe-000427-L1 for qemu-devel@nongnu.org; Sun, 12 Jun 2016 22:32:13 -0400 Received: from mga11.intel.com ([192.55.52.93]:64188) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCHfe-000423-F5 for qemu-devel@nongnu.org; Sun, 12 Jun 2016 22:32:10 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP; 12 Jun 2016 19:32:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,464,1459839600"; d="scan'208";a="974256898" Received: from pengc-linux.bj.intel.com ([10.238.145.48]) by orsmga001.jf.intel.com with ESMTP; 12 Jun 2016 19:32:06 -0700 From: Chao Peng To: qemu-devel@nongnu.org Date: Mon, 13 Jun 2016 10:21:27 +0800 Message-Id: <1465784487-23482-1-git-send-email-chao.p.peng@linux.intel.com> X-Mailer: git-send-email 1.9.1 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.93 Subject: [Qemu-devel] [PATCH] target-i386: kvm: cache KVM_GET_SUPPORTED_CPUID data X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , Marcelo Tosatti , Eduardo Habkost , kvm@vger.kernel.org, Richard Henderson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP KVM_GET_SUPPORTED_CPUID ioctl is called frequently when initializing CPU. Depends on CPU features and CPU count, the number of calls can be extremely high which slows down QEMU booting significantly. In our testing, we saw 5922 calls with switches: -cpu SandyBridge -smp 6,sockets=6,cores=1,threads=1 This ioctl takes more than 100ms, which is almost half of the total QEMU startup time. While for most cases the data returned from two different invocations are not changed, that means, we can cache the data to avoid trapping into kernel for the second time. To make sure the cache safe one assumption is desirable: the ioctl is stateless. This is not true however, at least for some CPUID leaves. The good part is even the ioctl is not fully stateless, we can still cache the return value if we know the data is unchanged for the leaves we are interested in. Actually this should be true for most invocations and looks all the places in current code hold true. A non-cached version can be introduced if refresh is required in the future. Signed-off-by: Chao Peng --- target-i386/kvm.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index abf50e6..1a4d751 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -107,6 +107,8 @@ static int has_xsave; static int has_xcrs; static int has_pit_state2; +static struct kvm_cpuid2 *cpuid_cache; + int kvm_has_pit_state2(void) { return has_pit_state2; @@ -200,9 +202,14 @@ static struct kvm_cpuid2 *get_supported_cpuid(KVMState *s) { struct kvm_cpuid2 *cpuid; int max = 1; + + if (cpuid_cache != NULL) { + return cpuid_cache; + } while ((cpuid = try_get_cpuid(s, max)) == NULL) { max *= 2; } + cpuid_cache = cpuid; return cpuid; } @@ -320,8 +327,6 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, ret |= cpuid_1_edx & CPUID_EXT2_AMD_ALIASES; } - g_free(cpuid); - /* fallback for older kernels */ if ((function == KVM_CPUID_FEATURES) && !found) { ret = get_para_features(s); @@ -1090,6 +1095,12 @@ static void register_smram_listener(Notifier *n, void *unused) &smram_address_space, 1); } +static Notifier kvm_exit_notifier; +static void kvm_arch_destroy(Notifier *n, void *unused) +{ + g_free(cpuid_cache); +} + int kvm_arch_init(MachineState *ms, KVMState *s) { uint64_t identity_base = 0xfffbc000; @@ -1165,6 +1176,9 @@ int kvm_arch_init(MachineState *ms, KVMState *s) smram_machine_done.notify = register_smram_listener; qemu_add_machine_init_done_notifier(&smram_machine_done); } + + kvm_exit_notifier.notify = kvm_arch_destroy; + qemu_add_exit_notifier(&kvm_exit_notifier); return 0; }