From patchwork Thu Nov 30 14:41:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13474543 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 D2353C4167B for ; Thu, 30 Nov 2023 14:38:24 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r8i6E-0003pw-HN; Thu, 30 Nov 2023 09:33:06 -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 1r8i6B-0003gj-Hk; Thu, 30 Nov 2023 09:33:03 -0500 Received: from mgamail.intel.com ([192.55.52.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r8i65-0001EW-Ja; Thu, 30 Nov 2023 09:33:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1701354777; x=1732890777; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=rj2qhjfojWttufVsjPIiSdC7tmdmcTNlZ7nywO+2iko=; b=dO4Aez7JrHM7v38FGTfGLWF0uORB5obZxpc3iXPJf7dbriTn8K4H9FcD 6losTWfcMEH82P+iZs/jWXJHH1ummgG/PPkzxPs0Rorw43dUxq8zvYPJ0 VmW/FtwiGNf1Sv1yrR43JJBtseVV80M8cPYMDe+ETUkpFtE3zaeSRqlT+ tY2LcLshTuI2jUqMGMzt3Ose8jHnE0u1Rcbg6QPWvCW2y7wekVSxWwaSJ 9Vv+Pn+5qMIpvXCzFMD1IhWpghdUoh6SIitkAor7H04J3utXJXD/UhmJP ebzw45PAHCKFgHhLrhy3JKz1V1YEauijAX4OBl51nvuit2jmyP8msOk8M g==; X-IronPort-AV: E=McAfee;i="6600,9927,10910"; a="479531720" X-IronPort-AV: E=Sophos;i="6.04,239,1695711600"; d="scan'208";a="479531720" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2023 06:32:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10910"; a="942729870" X-IronPort-AV: E=Sophos;i="6.04,239,1695711600"; d="scan'208";a="942729870" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orsmga005.jf.intel.com with ESMTP; 30 Nov 2023 06:32:26 -0800 From: Zhao Liu To: Paolo Bonzini , =?utf-8?q?Alex_Benn=C3=A9e?= , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Eduardo Habkost , Marcel Apfelbaum , Yanan Wang , Richard Henderson , "Michael S . Tsirkin" , Jason Wang , Nicholas Piggin , Daniel Henrique Barboza , Igor Mammedov , =?utf-8?q?C=C3=A9dric_Le_Goater?= , =?utf-8?b?RnLDqWTDqXJp?= =?utf-8?b?YyBCYXJyYXQ=?= , David Gibson , Harsh Prateek Bora , Stefano Stabellini , Anthony Perard , Paul Durrant , Gerd Hoffmann , Peter Maydell , Alistair Francis , "Edgar E . Iglesias" , =?utf-8?q?Daniel_P_=2E_Ber?= =?utf-8?q?rang=C3=A9?= , Bin Meng , Palmer Dabbelt , Weiwei Li , Liu Zhiwei , qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, xen-devel@lists.xenproject.org, qemu-arm@nongnu.org, qemu-riscv@nongnu.org, qemu-s390x@nongnu.org Cc: Nina Schoetterl-Glausch , Thomas Huth , Zhiyuan Lv , Zhenyu Wang , Yongwei Ma , Zhao Liu Subject: [RFC 13/41] hw/core/cpu: Convert CPU from general device to topology device Date: Thu, 30 Nov 2023 22:41:35 +0800 Message-Id: <20231130144203.2307629-14-zhao1.liu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231130144203.2307629-1-zhao1.liu@linux.intel.com> References: <20231130144203.2307629-1-zhao1.liu@linux.intel.com> MIME-Version: 1.0 Received-SPF: none client-ip=192.55.52.43; envelope-from=zhao1.liu@linux.intel.com; helo=mgamail.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, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 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: Zhao Liu Convert CPU to topology device then its parent topology devices could count the number of CPUs when new CPUs are added into topology tree. Note since CPUs are created from *_init_cpus() in MachineClass.init() or added from hotplug way, it depends on board initialization. Thus CPU topology device isn't marked as DEVICE_CATEGORY_CPU_DEF and it will only be created after board initialization. Signed-off-by: Zhao Liu --- accel/kvm/kvm-all.c | 4 ++-- hw/core/cpu-common.c | 25 +++++++++++++++++++++---- include/hw/core/cpu.h | 8 ++++++-- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index e39a810a4e92..2eee3eb95907 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -3953,7 +3953,7 @@ static void query_stats(StatsResultList **result, StatsTarget target, break; case STATS_TARGET_VCPU: add_stats_entry(result, STATS_PROVIDER_KVM, - cpu->parent_obj.canonical_path, + DEVICE(cpu)->canonical_path, stats_list); break; default: @@ -4045,7 +4045,7 @@ static void query_stats_cb(StatsResultList **result, StatsTarget target, stats_args.names = names; stats_args.errp = errp; CPU_FOREACH(cpu) { - if (!apply_str_list_filter(cpu->parent_obj.canonical_path, targets)) { + if (!apply_str_list_filter(DEVICE(cpu)->canonical_path, targets)) { continue; } query_stats_vcpu(cpu, &stats_args); diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index 82dae51a550b..e9ed84ff5386 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -195,6 +195,16 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) { CPUState *cpu = CPU(dev); Object *machine = qdev_get_machine(); + CPUClass *cc = CPU_GET_CLASS(cpu); + + /* + * The parent topology realize() must be completed before cpu_resume() + * where the CPU starts to run. + */ + cc->parent_realize(dev, errp); + if (*errp) { + return; + } /* qdev_get_machine() can return something that's not TYPE_MACHINE * if this is one of the user-only emulators; in that case there's @@ -225,6 +235,7 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) static void cpu_common_unrealizefn(DeviceState *dev) { CPUState *cpu = CPU(dev); + CPUClass *cc = CPU_GET_CLASS(cpu); /* Call the plugin hook before clearing the cpu is fully unrealized */ if (tcg_enabled()) { @@ -233,6 +244,7 @@ static void cpu_common_unrealizefn(DeviceState *dev) /* NOTE: latest generic point before the cpu is fully unrealized */ cpu_exec_unrealizefn(cpu); + cc->parent_unrealize(dev); } static void cpu_common_initfn(Object *obj) @@ -275,6 +287,7 @@ static void cpu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); + CPUTopoClass *tc = CPU_TOPO_CLASS(klass); CPUClass *k = CPU_CLASS(klass); k->parse_features = cpu_common_parse_features; @@ -282,9 +295,6 @@ static void cpu_class_init(ObjectClass *klass, void *data) k->has_work = cpu_common_has_work; k->gdb_read_register = cpu_common_gdb_read_register; k->gdb_write_register = cpu_common_gdb_write_register; - set_bit(DEVICE_CATEGORY_CPU, dc->categories); - dc->realize = cpu_common_realizefn; - dc->unrealize = cpu_common_unrealizefn; rc->phases.hold = cpu_common_reset_hold; cpu_class_init_props(dc); /* @@ -292,11 +302,18 @@ static void cpu_class_init(ObjectClass *klass, void *data) * IRQs, adding reset handlers, halting non-first CPUs, ... */ dc->user_creatable = false; + /* CPU is the minimum granularity for hotplug. */ + dc->hotpluggable = true; + device_class_set_parent_realize(dc, cpu_common_realizefn, + &k->parent_realize); + device_class_set_parent_unrealize(dc, cpu_common_unrealizefn, + &k->parent_unrealize); + tc->level = CPU_TOPO_THREAD; } static const TypeInfo cpu_type_info = { .name = TYPE_CPU, - .parent = TYPE_DEVICE, + .parent = TYPE_CPU_TOPO, .instance_size = sizeof(CPUState), .instance_init = cpu_common_initfn, .instance_finalize = cpu_common_finalize, diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index c0c8320413e5..a700f7c39140 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -20,6 +20,7 @@ #ifndef QEMU_CPU_H #define QEMU_CPU_H +#include "hw/core/cpu-topo.h" #include "hw/qdev-core.h" #include "disas/dis-asm.h" #include "exec/cpu-common.h" @@ -146,7 +147,7 @@ struct SysemuCPUOps; */ struct CPUClass { /*< private >*/ - DeviceClass parent_class; + CPUTopoClass parent_class; /*< public >*/ ObjectClass *(*class_by_name)(const char *cpu_model); @@ -191,6 +192,9 @@ struct CPUClass { int reset_dump_flags; int gdb_num_core_regs; bool gdb_stop_before_watchpoint; + + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; }; /* @@ -456,7 +460,7 @@ struct qemu_work_item; */ struct CPUState { /*< private >*/ - DeviceState parent_obj; + CPUTopoState parent_obj; /* cache to avoid expensive CPU_GET_CLASS */ CPUClass *cc; /*< public >*/