diff --git a/cpus-common.c b/cpus-common.c index 59f751ecf917a90cf7f98fe1eb8f892dbc376e7a..98dd8c6ff1300792228d9f33b12c84e7ef0e16ae 100644 --- a/cpus-common.c +++ b/cpus-common.c @@ -84,7 +84,7 @@ void cpu_list_add(CPUState *cpu) } else { assert(!cpu_index_auto_assigned); } - QTAILQ_INSERT_TAIL(&cpus, cpu, node); + QTAILQ_INSERT_TAIL_RCU(&cpus, cpu, node); qemu_mutex_unlock(&qemu_cpu_list_lock); finish_safe_work(cpu); @@ -101,7 +101,7 @@ void cpu_list_remove(CPUState *cpu) assert(!(cpu_index_auto_assigned && cpu != QTAILQ_LAST(&cpus, CPUTailQ))); - QTAILQ_REMOVE(&cpus, cpu, node); + QTAILQ_REMOVE_RCU(&cpus, cpu, node); cpu->cpu_index = UNASSIGNED_CPU_INDEX; qemu_mutex_unlock(&qemu_cpu_list_lock); } diff --git a/cpus.c b/cpus.c index a5ea3eef804b7c5453da65f46f224a2aa81b6b47..91613491b70dc733cee6b83373d49edb4d6c8aaa 100644 --- a/cpus.c +++ b/cpus.c @@ -1491,7 +1491,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) atomic_mb_set(&cpu->exit_request, 0); } - qemu_tcg_rr_wait_io_event(cpu ? cpu : QTAILQ_FIRST(&cpus)); + qemu_tcg_rr_wait_io_event(cpu ? cpu : first_cpu); deal_with_unplugged_cpus(); } diff --git a/include/qom/cpu.h b/include/qom/cpu.h index ecf6ed556a9cc95a21888b82ecc4a87d22450566..dc130cd3072b124e77c502bbfc95f1ccc8b92d3c 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -26,6 +26,7 @@ #include "exec/memattrs.h" #include "qapi/qapi-types-run-state.h" #include "qemu/bitmap.h" +#include "qemu/rcu_queue.h" #include "qemu/queue.h" #include "qemu/thread.h" @@ -442,13 +443,11 @@ struct CPUState { QTAILQ_HEAD(CPUTailQ, CPUState); extern struct CPUTailQ cpus; -#define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node) -#define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node) +#define first_cpu QTAILQ_FIRST_RCU(&cpus) +#define CPU_NEXT(cpu) QTAILQ_NEXT_RCU(cpu, node) +#define CPU_FOREACH(cpu) QTAILQ_FOREACH_RCU(cpu, &cpus, node) #define CPU_FOREACH_SAFE(cpu, next_cpu) \ - QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu) -#define CPU_FOREACH_REVERSE(cpu) \ - QTAILQ_FOREACH_REVERSE(cpu, &cpus, CPUTailQ, node) -#define first_cpu QTAILQ_FIRST(&cpus) + QTAILQ_FOREACH_SAFE_RCU(cpu, &cpus, node, next_cpu) extern __thread CPUState *current_cpu; diff --git a/linux-user/main.c b/linux-user/main.c index ea00dd905729d0e8287b1a791f5351ac1530c782..923cbb753acc0b2cccec3ef5d23b87338c537a1c 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -126,7 +126,7 @@ void fork_end(int child) Discard information about the parent threads. */ CPU_FOREACH_SAFE(cpu, next_cpu) { if (cpu != thread_cpu) { - QTAILQ_REMOVE(&cpus, cpu, node); + QTAILQ_REMOVE_RCU(&cpus, cpu, node); } } qemu_init_cpu_list(); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 202aa777ad5a6f90a66f4c2f3d02c77828153515..3c3c1aec48f5648a155be3bf33792196baf64136 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8157,7 +8157,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, TaskState *ts; /* Remove the CPU from the list. */ - QTAILQ_REMOVE(&cpus, cpu, node); + QTAILQ_REMOVE_RCU(&cpus, cpu, node); cpu_list_unlock(); diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index 12e765ba1f8ccadb79832c4a5597a6c98ee0e84f..265d25c937bb2a2e1b190765a8e16c146d920f5a 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -1096,7 +1096,7 @@ void s390_set_qemu_cpu_model(uint16_t type, uint8_t gen, uint8_t ec_ga, const S390CPUDef *def = s390_find_cpu_def(type, gen, ec_ga, NULL); g_assert(def); - g_assert(QTAILQ_EMPTY(&cpus)); + g_assert(QTAILQ_EMPTY_RCU(&cpus)); /* TCG emulates some features that can usually not be enabled with * the emulated machine generation. Make sure they can be enabled