diff options
author | Claudio Fontana <cfontana@suse.de> | 2021-02-04 17:39:25 +0100 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-02-05 10:24:15 -1000 |
commit | b86f59c71552591a17dd21ba8f09654bfa19a31e (patch) | |
tree | c73b9240fa6c4dbf46fdf1b67d65f7d283997589 /accel | |
parent | 940e43aa30e0f793bd18b79221296cdf17724018 (diff) |
accel: replace struct CpusAccel with AccelOpsClass
This will allow us to centralize the registration of
the cpus.c module accelerator operations (in accel/accel-softmmu.c),
and trigger it automatically using object hierarchy lookup from the
new accel_init_interfaces() initialization step, depending just on
which accelerators are available in the code.
Rename all tcg-cpus.c, kvm-cpus.c, etc to tcg-accel-ops.c,
kvm-accel-ops.c, etc, matching the object type names.
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Message-Id: <20210204163931.7358-18-cfontana@suse.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'accel')
-rw-r--r-- | accel/accel-common.c | 11 | ||||
-rw-r--r-- | accel/accel-softmmu.c | 44 | ||||
-rw-r--r-- | accel/accel-softmmu.h | 15 | ||||
-rw-r--r-- | accel/kvm/kvm-accel-ops.c (renamed from accel/kvm/kvm-cpus.c) | 28 | ||||
-rw-r--r-- | accel/kvm/kvm-all.c | 2 | ||||
-rw-r--r-- | accel/kvm/kvm-cpus.h | 2 | ||||
-rw-r--r-- | accel/kvm/meson.build | 2 | ||||
-rw-r--r-- | accel/qtest/qtest.c | 23 | ||||
-rw-r--r-- | accel/tcg/meson.build | 8 | ||||
-rw-r--r-- | accel/tcg/tcg-accel-ops-icount.c (renamed from accel/tcg/tcg-cpus-icount.c) | 21 | ||||
-rw-r--r-- | accel/tcg/tcg-accel-ops-icount.h (renamed from accel/tcg/tcg-cpus-icount.h) | 2 | ||||
-rw-r--r-- | accel/tcg/tcg-accel-ops-mttcg.c (renamed from accel/tcg/tcg-cpus-mttcg.c) | 14 | ||||
-rw-r--r-- | accel/tcg/tcg-accel-ops-mttcg.h | 19 | ||||
-rw-r--r-- | accel/tcg/tcg-accel-ops-rr.c (renamed from accel/tcg/tcg-cpus-rr.c) | 13 | ||||
-rw-r--r-- | accel/tcg/tcg-accel-ops-rr.h (renamed from accel/tcg/tcg-cpus-rr.h) | 0 | ||||
-rw-r--r-- | accel/tcg/tcg-accel-ops.c (renamed from accel/tcg/tcg-cpus.c) | 47 | ||||
-rw-r--r-- | accel/tcg/tcg-accel-ops.h (renamed from accel/tcg/tcg-cpus.h) | 6 | ||||
-rw-r--r-- | accel/tcg/tcg-all.c | 12 | ||||
-rw-r--r-- | accel/xen/xen-all.c | 24 |
19 files changed, 207 insertions, 86 deletions
diff --git a/accel/accel-common.c b/accel/accel-common.c index ddec8cb5ae..6b59873419 100644 --- a/accel/accel-common.c +++ b/accel/accel-common.c @@ -26,6 +26,10 @@ #include "qemu/osdep.h" #include "qemu/accel.h" +#ifndef CONFIG_USER_ONLY +#include "accel-softmmu.h" +#endif /* !CONFIG_USER_ONLY */ + static const TypeInfo accel_type = { .name = TYPE_ACCEL, .parent = TYPE_OBJECT, @@ -42,6 +46,13 @@ AccelClass *accel_find(const char *opt_name) return ac; } +void accel_init_interfaces(AccelClass *ac) +{ +#ifndef CONFIG_USER_ONLY + accel_init_ops_interfaces(ac); +#endif /* !CONFIG_USER_ONLY */ +} + static void register_accel_types(void) { type_register_static(&accel_type); diff --git a/accel/accel-softmmu.c b/accel/accel-softmmu.c index f89da8f9d1..50fa5acaa4 100644 --- a/accel/accel-softmmu.c +++ b/accel/accel-softmmu.c @@ -26,9 +26,9 @@ #include "qemu/osdep.h" #include "qemu/accel.h" #include "hw/boards.h" -#include "sysemu/arch_init.h" -#include "sysemu/sysemu.h" -#include "qom/object.h" +#include "sysemu/cpus.h" + +#include "accel-softmmu.h" int accel_init_machine(AccelState *accel, MachineState *ms) { @@ -60,3 +60,41 @@ void accel_setup_post(MachineState *ms) acc->setup_post(ms, accel); } } + +/* initialize the arch-independent accel operation interfaces */ +void accel_init_ops_interfaces(AccelClass *ac) +{ + const char *ac_name; + char *ops_name; + AccelOpsClass *ops; + + ac_name = object_class_get_name(OBJECT_CLASS(ac)); + g_assert(ac_name != NULL); + + ops_name = g_strdup_printf("%s" ACCEL_OPS_SUFFIX, ac_name); + ops = ACCEL_OPS_CLASS(object_class_by_name(ops_name)); + g_free(ops_name); + + /* + * all accelerators need to define ops, providing at least a mandatory + * non-NULL create_vcpu_thread operation. + */ + g_assert(ops != NULL); + if (ops->ops_init) { + ops->ops_init(ops); + } + cpus_register_accel(ops); +} + +static const TypeInfo accel_ops_type_info = { + .name = TYPE_ACCEL_OPS, + .parent = TYPE_OBJECT, + .abstract = true, + .class_size = sizeof(AccelOpsClass), +}; + +static void accel_softmmu_register_types(void) +{ + type_register_static(&accel_ops_type_info); +} +type_init(accel_softmmu_register_types); diff --git a/accel/accel-softmmu.h b/accel/accel-softmmu.h new file mode 100644 index 0000000000..5e192f1882 --- /dev/null +++ b/accel/accel-softmmu.h @@ -0,0 +1,15 @@ +/* + * QEMU System Emulation accel internal functions + * + * Copyright 2021 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef ACCEL_SOFTMMU_H +#define ACCEL_SOFTMMU_H + +void accel_init_ops_interfaces(AccelClass *ac); + +#endif /* ACCEL_SOFTMMU_H */ diff --git a/accel/kvm/kvm-cpus.c b/accel/kvm/kvm-accel-ops.c index d809b1e74c..7516c67a3f 100644 --- a/accel/kvm/kvm-cpus.c +++ b/accel/kvm/kvm-accel-ops.c @@ -74,11 +74,27 @@ static void kvm_start_vcpu_thread(CPUState *cpu) cpu, QEMU_THREAD_JOINABLE); } -const CpusAccel kvm_cpus = { - .create_vcpu_thread = kvm_start_vcpu_thread, +static void kvm_accel_ops_class_init(ObjectClass *oc, void *data) +{ + AccelOpsClass *ops = ACCEL_OPS_CLASS(oc); + + ops->create_vcpu_thread = kvm_start_vcpu_thread; + ops->synchronize_post_reset = kvm_cpu_synchronize_post_reset; + ops->synchronize_post_init = kvm_cpu_synchronize_post_init; + ops->synchronize_state = kvm_cpu_synchronize_state; + ops->synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm; +} + +static const TypeInfo kvm_accel_ops_type = { + .name = ACCEL_OPS_NAME("kvm"), - .synchronize_post_reset = kvm_cpu_synchronize_post_reset, - .synchronize_post_init = kvm_cpu_synchronize_post_init, - .synchronize_state = kvm_cpu_synchronize_state, - .synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm, + .parent = TYPE_ACCEL_OPS, + .class_init = kvm_accel_ops_class_init, + .abstract = true, }; + +static void kvm_accel_ops_register_types(void) +{ + type_register_static(&kvm_accel_ops_type); +} +type_init(kvm_accel_ops_register_types); diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 3feb17d965..5164d838b9 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2256,8 +2256,6 @@ static int kvm_init(MachineState *ms) ret = ram_block_discard_disable(true); assert(!ret); } - - cpus_register_accel(&kvm_cpus); return 0; err: diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h index 3df732b816..bf0bd1bee4 100644 --- a/accel/kvm/kvm-cpus.h +++ b/accel/kvm/kvm-cpus.h @@ -12,8 +12,6 @@ #include "sysemu/cpus.h" -extern const CpusAccel kvm_cpus; - int kvm_init_vcpu(CPUState *cpu, Error **errp); int kvm_cpu_exec(CPUState *cpu); void kvm_destroy_vcpu(CPUState *cpu); diff --git a/accel/kvm/meson.build b/accel/kvm/meson.build index 7e9dafe24c..8d219bea50 100644 --- a/accel/kvm/meson.build +++ b/accel/kvm/meson.build @@ -1,7 +1,7 @@ kvm_ss = ss.source_set() kvm_ss.add(files( 'kvm-all.c', - 'kvm-cpus.c', + 'kvm-accel-ops.c', )) kvm_ss.add(when: 'CONFIG_SEV', if_false: files('sev-stub.c')) diff --git a/accel/qtest/qtest.c b/accel/qtest/qtest.c index b4e731cb2b..edb29f6fa4 100644 --- a/accel/qtest/qtest.c +++ b/accel/qtest/qtest.c @@ -25,14 +25,8 @@ #include "qemu/main-loop.h" #include "hw/core/cpu.h" -const CpusAccel qtest_cpus = { - .create_vcpu_thread = dummy_start_vcpu_thread, - .get_virtual_clock = qtest_get_virtual_clock, -}; - static int qtest_init_accel(MachineState *ms) { - cpus_register_accel(&qtest_cpus); return 0; } @@ -52,9 +46,26 @@ static const TypeInfo qtest_accel_type = { .class_init = qtest_accel_class_init, }; +static void qtest_accel_ops_class_init(ObjectClass *oc, void *data) +{ + AccelOpsClass *ops = ACCEL_OPS_CLASS(oc); + + ops->create_vcpu_thread = dummy_start_vcpu_thread; + ops->get_virtual_clock = qtest_get_virtual_clock; +}; + +static const TypeInfo qtest_accel_ops_type = { + .name = ACCEL_OPS_NAME("qtest"), + + .parent = TYPE_ACCEL_OPS, + .class_init = qtest_accel_ops_class_init, + .abstract = true, +}; + static void qtest_type_init(void) { type_register_static(&qtest_accel_type); + type_register_static(&qtest_accel_ops_type); } type_init(qtest_type_init); diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build index 424d9bb1fc..1236ac7b91 100644 --- a/accel/tcg/meson.build +++ b/accel/tcg/meson.build @@ -15,8 +15,8 @@ specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss) specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: files( 'cputlb.c', - 'tcg-cpus.c', - 'tcg-cpus-mttcg.c', - 'tcg-cpus-icount.c', - 'tcg-cpus-rr.c' + 'tcg-accel-ops.c', + 'tcg-accel-ops-mttcg.c', + 'tcg-accel-ops-icount.c', + 'tcg-accel-ops-rr.c' )) diff --git a/accel/tcg/tcg-cpus-icount.c b/accel/tcg/tcg-accel-ops-icount.c index 9f45432275..87762b469c 100644 --- a/accel/tcg/tcg-cpus-icount.c +++ b/accel/tcg/tcg-accel-ops-icount.c @@ -32,9 +32,9 @@ #include "exec/exec-all.h" #include "hw/boards.h" -#include "tcg-cpus.h" -#include "tcg-cpus-icount.h" -#include "tcg-cpus-rr.h" +#include "tcg-accel-ops.h" +#include "tcg-accel-ops-icount.h" +#include "tcg-accel-ops-rr.h" static int64_t icount_get_limit(void) { @@ -93,7 +93,7 @@ void icount_prepare_for_run(CPUState *cpu) /* * These should always be cleared by icount_process_data after * each vCPU execution. However u16.high can be raised - * asynchronously by cpu_exit/cpu_interrupt/tcg_cpus_handle_interrupt + * asynchronously by cpu_exit/cpu_interrupt/tcg_handle_interrupt */ g_assert(cpu_neg(cpu)->icount_decr.u16.low == 0); g_assert(cpu->icount_extra == 0); @@ -125,23 +125,14 @@ void icount_process_data(CPUState *cpu) replay_mutex_unlock(); } -static void icount_handle_interrupt(CPUState *cpu, int mask) +void icount_handle_interrupt(CPUState *cpu, int mask) { int old_mask = cpu->interrupt_request; - tcg_cpus_handle_interrupt(cpu, mask); + tcg_handle_interrupt(cpu, mask); if (qemu_cpu_is_self(cpu) && !cpu->can_do_io && (mask & ~old_mask) != 0) { cpu_abort(cpu, "Raised interrupt while not in I/O function"); } } - -const CpusAccel tcg_cpus_icount = { - .create_vcpu_thread = rr_start_vcpu_thread, - .kick_vcpu_thread = rr_kick_vcpu_thread, - - .handle_interrupt = icount_handle_interrupt, - .get_virtual_clock = icount_get, - .get_elapsed_ticks = icount_get, -}; diff --git a/accel/tcg/tcg-cpus-icount.h b/accel/tcg/tcg-accel-ops-icount.h index b695939dfa..d884aa2aaa 100644 --- a/accel/tcg/tcg-cpus-icount.h +++ b/accel/tcg/tcg-accel-ops-icount.h @@ -14,4 +14,6 @@ void icount_handle_deadline(void); void icount_prepare_for_run(CPUState *cpu); void icount_process_data(CPUState *cpu); +void icount_handle_interrupt(CPUState *cpu, int mask); + #endif /* TCG_CPUS_ICOUNT_H */ diff --git a/accel/tcg/tcg-cpus-mttcg.c b/accel/tcg/tcg-accel-ops-mttcg.c index 9c3767d260..42973fb062 100644 --- a/accel/tcg/tcg-cpus-mttcg.c +++ b/accel/tcg/tcg-accel-ops-mttcg.c @@ -32,7 +32,8 @@ #include "exec/exec-all.h" #include "hw/boards.h" -#include "tcg-cpus.h" +#include "tcg-accel-ops.h" +#include "tcg-accel-ops-mttcg.h" /* * In the multi-threaded case each vCPU has its own thread. The TLS @@ -103,12 +104,12 @@ static void *mttcg_cpu_thread_fn(void *arg) return NULL; } -static void mttcg_kick_vcpu_thread(CPUState *cpu) +void mttcg_kick_vcpu_thread(CPUState *cpu) { cpu_exit(cpu); } -static void mttcg_start_vcpu_thread(CPUState *cpu) +void mttcg_start_vcpu_thread(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; @@ -131,10 +132,3 @@ static void mttcg_start_vcpu_thread(CPUState *cpu) cpu->hThread = qemu_thread_get_handle(cpu->thread); #endif } - -const CpusAccel tcg_cpus_mttcg = { - .create_vcpu_thread = mttcg_start_vcpu_thread, - .kick_vcpu_thread = mttcg_kick_vcpu_thread, - - .handle_interrupt = tcg_cpus_handle_interrupt, -}; diff --git a/accel/tcg/tcg-accel-ops-mttcg.h b/accel/tcg/tcg-accel-ops-mttcg.h new file mode 100644 index 0000000000..9fdc5a2ab5 --- /dev/null +++ b/accel/tcg/tcg-accel-ops-mttcg.h @@ -0,0 +1,19 @@ +/* + * QEMU TCG Multi Threaded vCPUs implementation + * + * Copyright 2021 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef TCG_CPUS_MTTCG_H +#define TCG_CPUS_MTTCG_H + +/* kick MTTCG vCPU thread */ +void mttcg_kick_vcpu_thread(CPUState *cpu); + +/* start an mttcg vCPU thread */ +void mttcg_start_vcpu_thread(CPUState *cpu); + +#endif /* TCG_CPUS_MTTCG_H */ diff --git a/accel/tcg/tcg-cpus-rr.c b/accel/tcg/tcg-accel-ops-rr.c index 0181d2e4eb..4a66055e0d 100644 --- a/accel/tcg/tcg-cpus-rr.c +++ b/accel/tcg/tcg-accel-ops-rr.c @@ -32,9 +32,9 @@ #include "exec/exec-all.h" #include "hw/boards.h" -#include "tcg-cpus.h" -#include "tcg-cpus-rr.h" -#include "tcg-cpus-icount.h" +#include "tcg-accel-ops.h" +#include "tcg-accel-ops-rr.h" +#include "tcg-accel-ops-icount.h" /* Kick all RR vCPUs */ void rr_kick_vcpu_thread(CPUState *unused) @@ -296,10 +296,3 @@ void rr_start_vcpu_thread(CPUState *cpu) cpu->created = true; } } - -const CpusAccel tcg_cpus_rr = { - .create_vcpu_thread = rr_start_vcpu_thread, - .kick_vcpu_thread = rr_kick_vcpu_thread, - - .handle_interrupt = tcg_cpus_handle_interrupt, -}; diff --git a/accel/tcg/tcg-cpus-rr.h b/accel/tcg/tcg-accel-ops-rr.h index 54f6ae6e86..54f6ae6e86 100644 --- a/accel/tcg/tcg-cpus-rr.h +++ b/accel/tcg/tcg-accel-ops-rr.h diff --git a/accel/tcg/tcg-cpus.c b/accel/tcg/tcg-accel-ops.c index e335f9f155..6144d9df87 100644 --- a/accel/tcg/tcg-cpus.c +++ b/accel/tcg/tcg-accel-ops.c @@ -34,7 +34,10 @@ #include "exec/exec-all.h" #include "hw/boards.h" -#include "tcg-cpus.h" +#include "tcg-accel-ops.h" +#include "tcg-accel-ops-mttcg.h" +#include "tcg-accel-ops-rr.h" +#include "tcg-accel-ops-icount.h" /* common functionality among all TCG variants */ @@ -64,7 +67,7 @@ int tcg_cpus_exec(CPUState *cpu) } /* mask must never be zero, except for A20 change call */ -void tcg_cpus_handle_interrupt(CPUState *cpu, int mask) +void tcg_handle_interrupt(CPUState *cpu, int mask) { g_assert(qemu_mutex_iothread_locked()); @@ -80,3 +83,43 @@ void tcg_cpus_handle_interrupt(CPUState *cpu, int mask) qatomic_set(&cpu_neg(cpu)->icount_decr.u16.high, -1); } } + +static void tcg_accel_ops_init(AccelOpsClass *ops) +{ + if (qemu_tcg_mttcg_enabled()) { + ops->create_vcpu_thread = mttcg_start_vcpu_thread; + ops->kick_vcpu_thread = mttcg_kick_vcpu_thread; + ops->handle_interrupt = tcg_handle_interrupt; + } else if (icount_enabled()) { + ops->create_vcpu_thread = rr_start_vcpu_thread; + ops->kick_vcpu_thread = rr_kick_vcpu_thread; + ops->handle_interrupt = icount_handle_interrupt; + ops->get_virtual_clock = icount_get; + ops->get_elapsed_ticks = icount_get; + } else { + ops->create_vcpu_thread = rr_start_vcpu_thread; + ops->kick_vcpu_thread = rr_kick_vcpu_thread; + ops->handle_interrupt = tcg_handle_interrupt; + } +} + +static void tcg_accel_ops_class_init(ObjectClass *oc, void *data) +{ + AccelOpsClass *ops = ACCEL_OPS_CLASS(oc); + + ops->ops_init = tcg_accel_ops_init; +} + +static const TypeInfo tcg_accel_ops_type = { + .name = ACCEL_OPS_NAME("tcg"), + + .parent = TYPE_ACCEL_OPS, + .class_init = tcg_accel_ops_class_init, + .abstract = true, +}; + +static void tcg_accel_ops_register_types(void) +{ + type_register_static(&tcg_accel_ops_type); +} +type_init(tcg_accel_ops_register_types); diff --git a/accel/tcg/tcg-cpus.h b/accel/tcg/tcg-accel-ops.h index d6893a32f8..48130006de 100644 --- a/accel/tcg/tcg-cpus.h +++ b/accel/tcg/tcg-accel-ops.h @@ -14,12 +14,8 @@ #include "sysemu/cpus.h" -extern const CpusAccel tcg_cpus_mttcg; -extern const CpusAccel tcg_cpus_icount; -extern const CpusAccel tcg_cpus_rr; - void tcg_cpus_destroy(CPUState *cpu); int tcg_cpus_exec(CPUState *cpu); -void tcg_cpus_handle_interrupt(CPUState *cpu, int mask); +void tcg_handle_interrupt(CPUState *cpu, int mask); #endif /* TCG_CPUS_H */ diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c index 642a7b94a7..e378c2db73 100644 --- a/accel/tcg/tcg-all.c +++ b/accel/tcg/tcg-all.c @@ -33,10 +33,6 @@ #include "qemu/accel.h" #include "qapi/qapi-builtin-visit.h" -#ifndef CONFIG_USER_ONLY -#include "tcg-cpus.h" -#endif /* CONFIG_USER_ONLY */ - struct TCGState { AccelState parent_obj; @@ -124,14 +120,6 @@ static int tcg_init(MachineState *ms) */ #ifndef CONFIG_USER_ONLY tcg_region_init(); - - if (mttcg_enabled) { - cpus_register_accel(&tcg_cpus_mttcg); - } else if (icount_enabled()) { - cpus_register_accel(&tcg_cpus_icount); - } else { - cpus_register_accel(&tcg_cpus_rr); - } #endif /* !CONFIG_USER_ONLY */ return 0; diff --git a/accel/xen/xen-all.c b/accel/xen/xen-all.c index 594aaf6b49..e9d2d6aaaa 100644 --- a/accel/xen/xen-all.c +++ b/accel/xen/xen-all.c @@ -154,10 +154,6 @@ static void xen_setup_post(MachineState *ms, AccelState *accel) } } -const CpusAccel xen_cpus = { - .create_vcpu_thread = dummy_start_vcpu_thread, -}; - static int xen_init(MachineState *ms) { MachineClass *mc = MACHINE_GET_CLASS(ms); @@ -185,9 +181,6 @@ static int xen_init(MachineState *ms) * opt out of system RAM being allocated by generic code */ mc->default_ram_id = NULL; - - cpus_register_accel(&xen_cpus); - return 0; } @@ -222,9 +215,24 @@ static const TypeInfo xen_accel_type = { .class_init = xen_accel_class_init, }; +static void xen_accel_ops_class_init(ObjectClass *oc, void *data) +{ + AccelOpsClass *ops = ACCEL_OPS_CLASS(oc); + + ops->create_vcpu_thread = dummy_start_vcpu_thread; +} + +static const TypeInfo xen_accel_ops_type = { + .name = ACCEL_OPS_NAME("xen"), + + .parent = TYPE_ACCEL_OPS, + .class_init = xen_accel_ops_class_init, + .abstract = true, +}; + static void xen_type_init(void) { type_register_static(&xen_accel_type); + type_register_static(&xen_accel_ops_type); } - type_init(xen_type_init); |