From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38496) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yqex5-00088m-2O for qemu-devel@nongnu.org; Fri, 08 May 2015 05:52:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yqewz-0006DG-Um for qemu-devel@nongnu.org; Fri, 08 May 2015 05:52:15 -0400 Received: from e28smtp01.in.ibm.com ([122.248.162.1]:35743) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yqewz-0006Cq-05 for qemu-devel@nongnu.org; Fri, 08 May 2015 05:52:09 -0400 Received: from /spool/local by e28smtp01.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 8 May 2015 15:22:06 +0530 Received: from d28relay04.in.ibm.com (d28relay04.in.ibm.com [9.184.220.61]) by d28dlp03.in.ibm.com (Postfix) with ESMTP id 4FB32125805C for ; Fri, 8 May 2015 15:24:10 +0530 (IST) Received: from d28av02.in.ibm.com (d28av02.in.ibm.com [9.184.220.64]) by d28relay04.in.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t489pnSi21823652 for ; Fri, 8 May 2015 15:21:51 +0530 Received: from d28av02.in.ibm.com (localhost [127.0.0.1]) by d28av02.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t489H1PO020093 for ; Fri, 8 May 2015 14:47:01 +0530 From: Bharata B Rao Date: Fri, 8 May 2015 15:21:35 +0530 Message-Id: <1431078696-29519-3-git-send-email-bharata@linux.vnet.ibm.com> In-Reply-To: <1431078696-29519-1-git-send-email-bharata@linux.vnet.ibm.com> References: <1431078696-29519-1-git-send-email-bharata@linux.vnet.ibm.com> Subject: [Qemu-devel] [RFC v1 PATCH 2/3] cpus: Convert cpu_index into a bitmap List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: zhugh.fnst@cn.fujitsu.com, ehabkost@redhat.com, agraf@suse.de, Bharata B Rao , imammedo@redhat.com, afaerber@suse.de, david@gibson.dropbear.id.au Currently CPUState.cpu_index is monotonically increasing and a newly created CPU always gets the next higher index. The next available index is calculated by counting the existing number of CPUs. This is fine as long as we only add CPUs, but there are architectures which are starting to support CPU removal too. For an architecture like PowerPC which derives its CPU identifier (device tree ID) from cpu_index, the existing logic of generating cpu_index values causes problems. With the currently proposed method of handling vCPU removal by parking the vCPU fd in QEMU (Ref: http://lists.gnu.org/archive/html/qemu-devel/2015-02/msg02604.html), generating cpu_index this way will not work for PowerPC. This patch changes the way cpu_index is handed out by maintaining a bit map of the CPUs that tracks both addition and removal of CPUs. The CPU bitmap allocation logic is part of cpu_exec_init() which is called by instance_init routines of various CPU targets. This patch also adds corresponding instance_finalize routine if needed for these CPU targets so that CPU can be marked free when it is removed. Signed-off-by: Bharata B Rao --- exec.c | 37 ++++++++++++++++++++++++++++++++++--- include/qom/cpu.h | 8 ++++++++ target-alpha/cpu.c | 6 ++++++ target-arm/cpu.c | 1 + target-cris/cpu.c | 6 ++++++ target-i386/cpu.c | 6 ++++++ target-lm32/cpu.c | 6 ++++++ target-m68k/cpu.c | 6 ++++++ target-microblaze/cpu.c | 6 ++++++ target-mips/cpu.c | 6 ++++++ target-moxie/cpu.c | 6 ++++++ target-openrisc/cpu.c | 6 ++++++ target-ppc/translate_init.c | 6 ++++++ target-s390x/cpu.c | 1 + target-sh4/cpu.c | 6 ++++++ target-sparc/cpu.c | 1 + target-tricore/cpu.c | 5 +++++ target-unicore32/cpu.c | 6 ++++++ target-xtensa/cpu.c | 6 ++++++ 19 files changed, 128 insertions(+), 3 deletions(-) diff --git a/exec.c b/exec.c index 68b632b..2422948 100644 --- a/exec.c +++ b/exec.c @@ -519,21 +519,52 @@ void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as) } #endif +#ifndef CONFIG_USER_ONLY +static DECLARE_BITMAP(cpu_index_map, MAX_CPUMASK_BITS); + +static int cpu_get_free_index(Error **errp) +{ + int cpu = find_first_zero_bit(cpu_index_map, max_cpus); + + if (cpu == max_cpus) { + error_setg(errp, "Trying to use more CPUs than allowed max of %d\n", + max_cpus); + return max_cpus; + } else { + bitmap_set(cpu_index_map, cpu, 1); + return cpu; + } +} + +void cpu_exec_exit(CPUState *cpu) +{ + bitmap_clear(cpu_index_map, cpu->cpu_index, 1); +} +#endif + void cpu_exec_init(CPUArchState *env, Error **errp) { CPUState *cpu = ENV_GET_CPU(env); CPUClass *cc = CPU_GET_CLASS(cpu); - CPUState *some_cpu; int cpu_index; - #if defined(CONFIG_USER_ONLY) + CPUState *some_cpu; + cpu_list_lock(); -#endif cpu_index = 0; CPU_FOREACH(some_cpu) { cpu_index++; } cpu->cpu_index = cpu_index; +#else + Error *local_err = NULL; + + cpu_index = cpu->cpu_index = cpu_get_free_index(&local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } +#endif cpu->numa_node = 0; QTAILQ_INIT(&cpu->breakpoints); QTAILQ_INIT(&cpu->watchpoints); diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 39f0f19..3611ce5 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -673,6 +673,14 @@ void cpu_watchpoint_remove_all(CPUState *cpu, int mask); void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...) GCC_FMT_ATTR(2, 3); +#ifndef CONFIG_USER_ONLY +void cpu_exec_exit(CPUState *cpu); +#else +static inline void cpu_exec_exit(CPUState *cpu) +{ +} +#endif + #ifdef CONFIG_SOFTMMU extern const struct VMStateDescription vmstate_cpu_common; #else diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index 0a0c21e..259a04c 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -250,6 +250,11 @@ static const TypeInfo ev68_cpu_type_info = { .parent = TYPE("ev67"), }; +static void alpha_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void alpha_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -305,6 +310,7 @@ static const TypeInfo alpha_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(AlphaCPU), .instance_init = alpha_cpu_initfn, + .instance_finalize = alpha_cpu_finalize, .abstract = true, .class_size = sizeof(AlphaCPUClass), .class_init = alpha_cpu_class_init, diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 0b27c19..ef04ae1 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -454,6 +454,7 @@ static void arm_cpu_finalizefn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); g_hash_table_destroy(cpu->cp_regs); + cpu_exec_exit(CPU(obj)); } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 8b589ec..da39223 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -161,6 +161,11 @@ static void cris_cpu_set_irq(void *opaque, int irq, int level) } #endif +static void cris_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void cris_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -299,6 +304,7 @@ static const TypeInfo cris_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(CRISCPU), .instance_init = cris_cpu_initfn, + .instance_finalize = cris_cpu_finalize, .abstract = true, .class_size = sizeof(CRISCPUClass), .class_init = cris_cpu_class_init, diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 72e8fa9..7305cdc 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2841,6 +2841,11 @@ out: } } +static void x86_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void x86_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -3010,6 +3015,7 @@ static const TypeInfo x86_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(X86CPU), .instance_init = x86_cpu_initfn, + .instance_finalize = x86_cpu_finalize, .abstract = true, .class_size = sizeof(X86CPUClass), .class_init = x86_cpu_common_class_init, diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index 89b6631..d7bc973 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -143,6 +143,11 @@ static void lm32_cpu_realizefn(DeviceState *dev, Error **errp) lcc->parent_realize(dev, errp); } +static void lm32_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void lm32_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -294,6 +299,7 @@ static const TypeInfo lm32_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(LM32CPU), .instance_init = lm32_cpu_initfn, + .instance_finalize = lm32_cpu_finalize, .abstract = true, .class_size = sizeof(LM32CPUClass), .class_init = lm32_cpu_class_init, diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 6a41551..c2fce97 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -160,6 +160,11 @@ static void m68k_cpu_realizefn(DeviceState *dev, Error **errp) mcc->parent_realize(dev, errp); } +static void m68k_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void m68k_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -231,6 +236,7 @@ static const TypeInfo m68k_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(M68kCPU), .instance_init = m68k_cpu_initfn, + .instance_finalize = m68k_cpu_finalize, .abstract = true, .class_size = sizeof(M68kCPUClass), .class_init = m68k_cpu_class_init, diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index 6b3732d..3aa3796 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -122,6 +122,11 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **errp) mcc->parent_realize(dev, errp); } +static void mb_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void mb_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -190,6 +195,7 @@ static const TypeInfo mb_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(MicroBlazeCPU), .instance_init = mb_cpu_initfn, + .instance_finalize = mb_cpu_finalize, .class_size = sizeof(MicroBlazeCPUClass), .class_init = mb_cpu_class_init, }; diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 5eea836..0cadfff 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -108,6 +108,11 @@ static void mips_cpu_realizefn(DeviceState *dev, Error **errp) mcc->parent_realize(dev, errp); } +static void mips_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void mips_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -160,6 +165,7 @@ static const TypeInfo mips_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(MIPSCPU), .instance_init = mips_cpu_initfn, + .instance_finalize = mips_cpu_finalize, .abstract = false, .class_size = sizeof(MIPSCPUClass), .class_init = mips_cpu_class_init, diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c index f815fb3..25d5f30 100644 --- a/target-moxie/cpu.c +++ b/target-moxie/cpu.c @@ -59,6 +59,11 @@ static void moxie_cpu_realizefn(DeviceState *dev, Error **errp) mcc->parent_realize(dev, errp); } +static void moxie_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void moxie_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -160,6 +165,7 @@ static const TypeInfo moxie_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(MoxieCPU), .instance_init = moxie_cpu_initfn, + .instance_finalize = moxie_cpu_finalize, .class_size = sizeof(MoxieCPUClass), .class_init = moxie_cpu_class_init, }; diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index 87b2f80..f0c990f 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -85,6 +85,11 @@ static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp) occ->parent_realize(dev, errp); } +static void openrisc_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void openrisc_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -198,6 +203,7 @@ static const TypeInfo openrisc_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(OpenRISCCPU), .instance_init = openrisc_cpu_initfn, + .instance_finalize = openrisc_cpu_finalize, .abstract = true, .class_size = sizeof(OpenRISCCPUClass), .class_init = openrisc_cpu_class_init, diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 4665cf9..b915697 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -9625,6 +9625,11 @@ static bool ppc_cpu_is_big_endian(CPUState *cs) } #endif +static void ppc_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void ppc_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -9738,6 +9743,7 @@ static const TypeInfo ppc_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(PowerPCCPU), .instance_init = ppc_cpu_initfn, + .instance_finalize = ppc_cpu_finalize, .abstract = true, .class_size = sizeof(PowerPCCPUClass), .class_init = ppc_cpu_class_init, diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 22499bb..1370d4a 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -214,6 +214,7 @@ static void s390_cpu_finalize(Object *obj) qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu); #endif + cpu_exec_exit(CPU(obj)); } #if !defined(CONFIG_USER_ONLY) diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index ffb635e..65f44c7 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -240,6 +240,11 @@ static void superh_cpu_realizefn(DeviceState *dev, Error **errp) scc->parent_realize(dev, errp); } +static void superh_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void superh_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -296,6 +301,7 @@ static const TypeInfo superh_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(SuperHCPU), .instance_init = superh_cpu_initfn, + .instance_finalize = superh_cpu_finalize, .abstract = true, .class_size = sizeof(SuperHCPUClass), .class_init = superh_cpu_class_init, diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index d857aae..ac7091a 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -815,6 +815,7 @@ static void sparc_cpu_uninitfn(Object *obj) CPUSPARCState *env = &cpu->env; g_free(env->def); + cpu_exec_exit(CPU(obj)); } static void sparc_cpu_class_init(ObjectClass *oc, void *data) diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c index 53b117b..e871dc4 100644 --- a/target-tricore/cpu.c +++ b/target-tricore/cpu.c @@ -80,6 +80,10 @@ static void tricore_cpu_realizefn(DeviceState *dev, Error **errp) tcc->parent_realize(dev, errp); } +static void tricore_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} static void tricore_cpu_initfn(Object *obj) { @@ -180,6 +184,7 @@ static const TypeInfo tricore_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(TriCoreCPU), .instance_init = tricore_cpu_initfn, + .instance_finalize = tricore_cpu_finalize, .abstract = true, .class_size = sizeof(TriCoreCPUClass), .class_init = tricore_cpu_class_init, diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index d56d78a..64af9f8 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -103,6 +103,11 @@ static void uc32_cpu_realizefn(DeviceState *dev, Error **errp) ucc->parent_realize(dev, errp); } +static void uc32_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void uc32_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -174,6 +179,7 @@ static const TypeInfo uc32_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(UniCore32CPU), .instance_init = uc32_cpu_initfn, + .instance_finalize = uc32_cpu_finalize, .abstract = true, .class_size = sizeof(UniCore32CPUClass), .class_init = uc32_cpu_class_init, diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index 87178e6..e9d2a1e 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -104,6 +104,11 @@ static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp) xcc->parent_realize(dev, errp); } +static void xtensa_cpu_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static void xtensa_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -162,6 +167,7 @@ static const TypeInfo xtensa_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(XtensaCPU), .instance_init = xtensa_cpu_initfn, + .instance_finalize = xtensa_cpu_finalize, .abstract = true, .class_size = sizeof(XtensaCPUClass), .class_init = xtensa_cpu_class_init, -- 2.1.0