From patchwork Thu Feb 2 09:49:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13125635 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 13C0FC636D4 for ; Thu, 2 Feb 2023 09:44:02 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pNW7p-0006Sk-Lw; Thu, 02 Feb 2023 04:43:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pNW7o-0006SN-8M for qemu-devel@nongnu.org; Thu, 02 Feb 2023 04:43:24 -0500 Received: from mga02.intel.com ([134.134.136.20]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pNW7m-0006Mx-BF for qemu-devel@nongnu.org; Thu, 02 Feb 2023 04:43:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1675331002; x=1706867002; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ONIXpxjScTTyI+kXqVoanQmgfDC+9C4UoIt3+khElwU=; b=WPRiqrc9AydImuASzkgxI017FyI0K0X/VW5CE/IG36MferBtzFZcgJ5A P7811FucNZHPfY/uyLzWnBasMpWpIAR11bjqXiobBKbsKPofa9Cm2o0Ye DxZ1B4JPXhZ7hs63BoX66iMEGYIoRNE90yJ2OhbKENWRQ6LqYgPb6xzCB p2z+TV3PMb8oOGZQf7qQl6iPjIbrjG+CZclBdXipgiMz4kP3yzCU6Rozu 0jxlGLk0V8swTyoBnXkF1BIFq2/n+CnCPLDnva1maSLTQuLi8KSnPSo2Y 9QsnfULikT1ZoG6M1lmhNPf9hqeWxk3DIQY1cBFJnUv3vQslU3UHYa1Xe Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="316401926" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="316401926" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Feb 2023 01:42:05 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="807909388" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="807909388" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.112]) by fmsmga001.fm.intel.com with ESMTP; 02 Feb 2023 01:42:02 -0800 From: Zhao Liu To: Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Richard Henderson , Paolo Bonzini Cc: qemu-devel@nongnu.org, Zhenyu Wang , Zhao Liu , Zhuocheng Ding Subject: [PATCH 03/18] softmmu: Fix CPUSTATE.nr_cores' calculation Date: Thu, 2 Feb 2023 17:49:14 +0800 Message-Id: <20230202094929.343799-4-zhao1.liu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230202094929.343799-1-zhao1.liu@linux.intel.com> References: <20230202094929.343799-1-zhao1.liu@linux.intel.com> MIME-Version: 1.0 Received-SPF: none client-ip=134.134.136.20; envelope-from=zhao1.liu@linux.intel.com; helo=mga02.intel.com X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Zhuocheng Ding From CPUState.nr_cores' comment, it represents "number of cores within this CPU package". After 003f230 (machine: Tweak the order of topology members in struct CpuTopology), the meaning of smp.cores changed to "the number of cores in one die", but this commit missed to change CPUState.nr_cores' caculation, so that CPUState.nr_cores became wrong and now it misses to consider numbers of clusters and dies. At present, only i386 is using CPUState.nr_cores. But as for i386, which supports die level, the uses of CPUState.nr_cores are very confusing: Early uses are based on the meaning of "cores per package" (before die is introduced into i386), and later uses are based on "cores per die" (after die's introduction). This difference is due to that commit a94e142 (target/i386: Add CPUID.1F generation support for multi-dies PCMachine) misunderstood that CPUState.nr_cores means "cores per die" when caculated CPUID.1FH.01H:EBX. After that, the changes in i386 all followed this wrong understanding. With the influence of 003f230 and a94e142, for i386 currently the result of CPUState.nr_cores is "cores per die", thus the original uses of CPUState.cores based on the meaning of "cores per package" are wrong when mutiple dies exist: 1. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.01H:EBX[bits 23:16] is incorrect because it expects "cpus per package" but now the result is "cpus per die". 2. In cpu_x86_cpuid() of target/i386/cpu.c, for all leaves of CPUID.04H: EAX[bits 31:26] is incorrect because they expect "cpus per package" but now the result is "cpus per die". The error not only impacts the EAX caculation in cache_info_passthrough case, but also impacts other cases of setting cache topology for Intel CPU according to cpu topology (specifically, the incoming parameter "num_cores" expects "cores per package" in encode_cache_cpuid4()). 3. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.0BH.01H:EBX[bits 15:00] is incorrect because the EBX of 0BH.01H (core level) expects "cpus per package", which may be different with 1FH.01H (The reason is 1FH can support more levels. For QEMU, 1FH also supports die, 1FH.01H:EBX[bits 15:00] expects "cpus per die"). 4. In cpu_x86_cpuid() of target/i386/cpu.c, when CPUID.80000001H is caculated, here "cpus per package" is expected to be checked, but in fact, now it checks "cpus per die". Though "cpus per die" also works for this code logic, this isn't consistent with AMD's APM. 5. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.80000008H:ECX expects "cpus per package" but it obtains "cpus per die". 6. In simulate_rdmsr() of target/i386/hvf/x86_emu.c, in kvm_rdmsr_core_thread_count() of target/i386/kvm/kvm.c, and in helper_rdmsr() of target/i386/tcg/sysemu/misc_helper.c, MSR_CORE_THREAD_COUNT expects "cpus per package" and "cores per package", but in these functions, it obtains "cpus per die" and "cores per die". On the other hand, these uses are correct now (they are added in/after a94e142): 1. In cpu_x86_cpuid() of target/i386/cpu.c, topo_info.cores_per_die meets the actual meaning of CPUState.nr_cores ("cores per die"). 2. In cpu_x86_cpuid() of target/i386/cpu.c, vcpus_per_socket (in CPUID. 04H's caculation) considers number of dies, so it's correct. 3. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.1FH.01H:EBX[bits 15:00] needs "cpus per die" and it gets the correct result, and CPUID.1FH.02H:EBX[bits 15:00] gets correct "cpus per package". When CPUState.nr_cores is correctly changed to "cores per package" again , the above errors will be fixed without extra work, but the "currently" correct cases will go wrong and need special handling to pass correct "cpus/cores per die" they want. Thus in this patch, we fix CPUState.nr_cores' caculation to fit the original meaning "cores per package", as well as changing caculation of topo_info.cores_per_die, vcpus_per_socket and CPUID.1FH. In addition, in the nr_threads' comment, specify it represents the number of threads in the "core" to avoid confusion. Fixes: a94e142 (target/i386: Add CPUID.1F generation support for multi-dies PCMachine) Fixes: 003f230 (machine: Tweak the order of topology members in struct CpuTopology) Signed-off-by: Zhuocheng Ding Co-developed-by: Zhao Liu Signed-off-by: Zhao Liu --- include/hw/core/cpu.h | 2 +- softmmu/cpus.c | 2 +- target/i386/cpu.c | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 2417597236bc..5253e4e839bb 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -274,7 +274,7 @@ struct qemu_work_item; * QOM parent. * @tcg_cflags: Pre-computed cflags for this cpu. * @nr_cores: Number of cores within this CPU package. - * @nr_threads: Number of threads within this CPU. + * @nr_threads: Number of threads within this CPU core. * @running: #true if CPU is currently running (lockless). * @has_waiter: #true if a CPU is currently waiting for the cpu_exec_end; * valid under cpu_list_lock. diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 9cbc8172b5f2..9996e6a3b295 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -630,7 +630,7 @@ void qemu_init_vcpu(CPUState *cpu) { MachineState *ms = MACHINE(qdev_get_machine()); - cpu->nr_cores = ms->smp.cores; + cpu->nr_cores = ms->smp.dies * ms->smp.clusters * ms->smp.cores; cpu->nr_threads = ms->smp.threads; cpu->stopped = true; cpu->random_seed = qemu_guest_random_seed_thread_part1(); diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 4d2b8d0444df..29afec12c281 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -5218,7 +5218,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, X86CPUTopoInfo topo_info; topo_info.dies_per_pkg = env->nr_dies; - topo_info.cores_per_die = cs->nr_cores; + topo_info.cores_per_die = cs->nr_cores / env->nr_dies; topo_info.threads_per_core = cs->nr_threads; /* Calculate & apply limits for different index ranges */ @@ -5294,8 +5294,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, */ if (*eax & 31) { int host_vcpus_per_cache = 1 + ((*eax & 0x3FFC000) >> 14); - int vcpus_per_socket = env->nr_dies * cs->nr_cores * - cs->nr_threads; + int vcpus_per_socket = cs->nr_cores * cs->nr_threads; if (cs->nr_cores > 1) { *eax &= ~0xFC000000; *eax |= (pow2ceil(cs->nr_cores) - 1) << 26; @@ -5468,12 +5467,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, break; case 1: *eax = apicid_die_offset(&topo_info); - *ebx = cs->nr_cores * cs->nr_threads; + *ebx = topo_info.cores_per_die * topo_info.threads_per_core; *ecx |= CPUID_TOPOLOGY_LEVEL_CORE; break; case 2: *eax = apicid_pkg_offset(&topo_info); - *ebx = env->nr_dies * cs->nr_cores * cs->nr_threads; + *ebx = cs->nr_cores * cs->nr_threads; *ecx |= CPUID_TOPOLOGY_LEVEL_DIE; break; default: