[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 2/7] cpus: Introduce AccelOpsClass::get_cpus_queue()
From: |
Philippe Mathieu-Daudé |
Subject: |
[RFC PATCH 2/7] cpus: Introduce AccelOpsClass::get_cpus_queue() |
Date: |
Mon, 6 Jan 2025 21:02:53 +0100 |
We want the ability to iterate over vCPUs of a specific
accelerator. Introduce cpus_get_accel_cpus_queue() to
be used by accelerator common code, and expose the
get_cpus_queue() in AccelOpsClass, so each accelerator
can register its own queue of vCPUs.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/core/cpu.h | 8 ++++++++
include/system/accel-ops.h | 6 ++++++
accel/tcg/user-exec-stub.c | 5 +++++
cpu-common.c | 10 ++++++++++
system/cpus.c | 5 +++++
5 files changed, 34 insertions(+)
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 48d90f50a71..5ae9bb64d6e 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -591,6 +591,14 @@ static inline CPUArchState *cpu_env(CPUState *cpu)
typedef QTAILQ_HEAD(CPUTailQ, CPUState) CPUTailQ;
extern CPUTailQ cpus_queue;
+/**
+ * cpus_get_accel_cpus_queue:
+ * @cpu: The vCPU to get the accelerator #CPUTailQ.
+ *
+ * Returns the #CPUTailQ associated with the accelerator of the vCPU.
+ */
+CPUTailQ *cpus_get_accel_cpus_queue(CPUState *cpu);
+
#define first_cpu QTAILQ_FIRST_RCU(&cpus_queue)
#define CPU_NEXT(cpu) QTAILQ_NEXT_RCU(cpu, node)
#define CPU_FOREACH(cpu) QTAILQ_FOREACH_RCU(cpu, &cpus_queue, node)
diff --git a/include/system/accel-ops.h b/include/system/accel-ops.h
index 137fb96d444..fe59f728bfc 100644
--- a/include/system/accel-ops.h
+++ b/include/system/accel-ops.h
@@ -12,6 +12,7 @@
#include "exec/vaddr.h"
#include "qom/object.h"
+#include "hw/core/cpu.h"
#define ACCEL_OPS_SUFFIX "-ops"
#define TYPE_ACCEL_OPS "accel" ACCEL_OPS_SUFFIX
@@ -37,6 +38,11 @@ struct AccelOpsClass {
bool (*cpus_are_resettable)(void);
void (*cpu_reset_hold)(CPUState *cpu);
+ /**
+ * get_cpus_queue:
+ * Returns the #CPUTailQ maintained by this accelerator.
+ */
+ CPUTailQ *(*get_cpus_queue)(void);
void (*create_vcpu_thread)(CPUState *cpu); /* MANDATORY NON-NULL */
void (*kick_vcpu_thread)(CPUState *cpu);
bool (*cpu_thread_is_idle)(CPUState *cpu);
diff --git a/accel/tcg/user-exec-stub.c b/accel/tcg/user-exec-stub.c
index 4fbe2dbdc88..cb76cec76be 100644
--- a/accel/tcg/user-exec-stub.c
+++ b/accel/tcg/user-exec-stub.c
@@ -18,6 +18,11 @@ void cpu_exec_reset_hold(CPUState *cpu)
{
}
+CPUTailQ *cpus_get_accel_cpus_queue(CPUState *cpu)
+{
+ return NULL;
+}
+
/* User mode emulation does not support record/replay yet. */
bool replay_exception(void)
diff --git a/cpu-common.c b/cpu-common.c
index 4248b2d727e..ff8db9c7f9d 100644
--- a/cpu-common.c
+++ b/cpu-common.c
@@ -82,6 +82,7 @@ unsigned int cpu_list_generation_id_get(void)
void cpu_list_add(CPUState *cpu)
{
static bool cpu_index_auto_assigned;
+ CPUTailQ *accel_cpus_queue = cpus_get_accel_cpus_queue(cpu);
QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
if (cpu->cpu_index == UNASSIGNED_CPU_INDEX) {
@@ -92,17 +93,26 @@ void cpu_list_add(CPUState *cpu)
assert(!cpu_index_auto_assigned);
}
QTAILQ_INSERT_TAIL_RCU(&cpus_queue, cpu, node);
+ if (accel_cpus_queue) {
+ QTAILQ_INSERT_TAIL_RCU(accel_cpus_queue, cpu, node);
+ }
+
cpu_list_generation_id++;
}
void cpu_list_remove(CPUState *cpu)
{
+ CPUTailQ *accel_cpus_queue = cpus_get_accel_cpus_queue(cpu);
+
QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
if (!QTAILQ_IN_USE(cpu, node)) {
/* there is nothing to undo since cpu_exec_init() hasn't been called */
return;
}
+ if (accel_cpus_queue) {
+ QTAILQ_REMOVE_RCU(accel_cpus_queue, cpu, node);
+ }
QTAILQ_REMOVE_RCU(&cpus_queue, cpu, node);
cpu->cpu_index = UNASSIGNED_CPU_INDEX;
cpu_list_generation_id++;
diff --git a/system/cpus.c b/system/cpus.c
index 99f83806c16..972df6ab061 100644
--- a/system/cpus.c
+++ b/system/cpus.c
@@ -209,6 +209,11 @@ void cpu_exec_reset_hold(CPUState *cpu)
}
}
+CPUTailQ *cpus_get_accel_cpus_queue(CPUState *cpu)
+{
+ return cpus_accel ? cpus_accel->get_cpus_queue() : NULL;
+}
+
int64_t cpus_get_virtual_clock(void)
{
/*
--
2.47.1
- [RFC PATCH 0/7] accel: Add per-accelerator vCPUs queue, Philippe Mathieu-Daudé, 2025/01/06
- [RFC PATCH 1/7] cpus: Restrict CPU_FOREACH_SAFE() to user emulation, Philippe Mathieu-Daudé, 2025/01/06
- [RFC PATCH 2/7] cpus: Introduce AccelOpsClass::get_cpus_queue(),
Philippe Mathieu-Daudé <=
- [RFC PATCH 3/7] accel/tcg: Implement tcg_get_cpus_queue(), Philippe Mathieu-Daudé, 2025/01/06
- [RFC PATCH 4/7] accel/tcg: Use CPU_FOREACH_TCG(), Philippe Mathieu-Daudé, 2025/01/06
- [RFC PATCH 5/7] accel/hw: Implement hw_accel_get_cpus_queue(), Philippe Mathieu-Daudé, 2025/01/06
- [RFC PATCH 6/7] accel/hvf: Use CPU_FOREACH_HVF(), Philippe Mathieu-Daudé, 2025/01/06
- [RFC PATCH 7/7] accel/kvm: Use CPU_FOREACH_KVM(), Philippe Mathieu-Daudé, 2025/01/06