Skip to content

Commit aaa6a40

Browse files
committed
Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
QOM CPUState refactorings / X86CPU * Conversion of global CPU list to QTAILQ - preparing for CPU hot-unplug * Document X86CPU magic numbers for CPUID cache info # gpg: Signature made Tue 03 Sep 2013 10:59:22 AM CDT using RSA key ID 3E7E013F # gpg: Can't check signature: public key not found # By Andreas Färber (3) and Eduardo Habkost (1) # Via Andreas Färber * afaerber/tags/qom-cpu-for-anthony: target-i386: Use #defines instead of magic numbers for CPUID cache info cpu: Replace qemu_for_each_cpu() cpu: Use QTAILQ for CPU list a15mpcore: Use qemu_get_cpu() for generic timers
2 parents bb7d4d8 + 5e891bf commit aaa6a40

31 files changed

+284
-199
lines changed

arch_init.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -1196,15 +1196,14 @@ static void mig_sleep_cpu(void *opq)
11961196
much time in the VM. The migration thread will try to catchup.
11971197
Workload will experience a performance drop.
11981198
*/
1199-
static void mig_throttle_cpu_down(CPUState *cpu, void *data)
1200-
{
1201-
async_run_on_cpu(cpu, mig_sleep_cpu, NULL);
1202-
}
1203-
12041199
static void mig_throttle_guest_down(void)
12051200
{
1201+
CPUState *cpu;
1202+
12061203
qemu_mutex_lock_iothread();
1207-
qemu_for_each_cpu(mig_throttle_cpu_down, NULL);
1204+
CPU_FOREACH(cpu) {
1205+
async_run_on_cpu(cpu, mig_sleep_cpu, NULL);
1206+
}
12081207
qemu_mutex_unlock_iothread();
12091208
}
12101209

cpus.c

+25-35
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static bool all_cpu_threads_idle(void)
8686
{
8787
CPUState *cpu;
8888

89-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
89+
CPU_FOREACH(cpu) {
9090
if (!cpu_thread_is_idle(cpu)) {
9191
return false;
9292
}
@@ -416,7 +416,7 @@ void hw_error(const char *fmt, ...)
416416
fprintf(stderr, "qemu: hardware error: ");
417417
vfprintf(stderr, fmt, ap);
418418
fprintf(stderr, "\n");
419-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
419+
CPU_FOREACH(cpu) {
420420
fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
421421
cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU);
422422
}
@@ -428,7 +428,7 @@ void cpu_synchronize_all_states(void)
428428
{
429429
CPUState *cpu;
430430

431-
for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
431+
CPU_FOREACH(cpu) {
432432
cpu_synchronize_state(cpu);
433433
}
434434
}
@@ -437,7 +437,7 @@ void cpu_synchronize_all_post_reset(void)
437437
{
438438
CPUState *cpu;
439439

440-
for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
440+
CPU_FOREACH(cpu) {
441441
cpu_synchronize_post_reset(cpu);
442442
}
443443
}
@@ -446,7 +446,7 @@ void cpu_synchronize_all_post_init(void)
446446
{
447447
CPUState *cpu;
448448

449-
for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
449+
CPU_FOREACH(cpu) {
450450
cpu_synchronize_post_init(cpu);
451451
}
452452
}
@@ -760,7 +760,7 @@ static void qemu_tcg_wait_io_event(void)
760760
qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
761761
}
762762

763-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
763+
CPU_FOREACH(cpu) {
764764
qemu_wait_io_event_common(cpu);
765765
}
766766
}
@@ -854,12 +854,6 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
854854

855855
static void tcg_exec_all(void);
856856

857-
static void tcg_signal_cpu_creation(CPUState *cpu, void *data)
858-
{
859-
cpu->thread_id = qemu_get_thread_id();
860-
cpu->created = true;
861-
}
862-
863857
static void *qemu_tcg_cpu_thread_fn(void *arg)
864858
{
865859
CPUState *cpu = arg;
@@ -868,15 +862,18 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
868862
qemu_thread_get_self(cpu->thread);
869863

870864
qemu_mutex_lock(&qemu_global_mutex);
871-
qemu_for_each_cpu(tcg_signal_cpu_creation, NULL);
865+
CPU_FOREACH(cpu) {
866+
cpu->thread_id = qemu_get_thread_id();
867+
cpu->created = true;
868+
}
872869
qemu_cond_signal(&qemu_cpu_cond);
873870

874871
/* wait for initial kick-off after machine start */
875-
while (first_cpu->stopped) {
872+
while (QTAILQ_FIRST(&cpus)->stopped) {
876873
qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
877874

878875
/* process any pending work */
879-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
876+
CPU_FOREACH(cpu) {
880877
qemu_wait_io_event_common(cpu);
881878
}
882879
}
@@ -991,48 +988,42 @@ void qemu_mutex_unlock_iothread(void)
991988

992989
static int all_vcpus_paused(void)
993990
{
994-
CPUState *cpu = first_cpu;
991+
CPUState *cpu;
995992

996-
while (cpu) {
993+
CPU_FOREACH(cpu) {
997994
if (!cpu->stopped) {
998995
return 0;
999996
}
1000-
cpu = cpu->next_cpu;
1001997
}
1002998

1003999
return 1;
10041000
}
10051001

10061002
void pause_all_vcpus(void)
10071003
{
1008-
CPUState *cpu = first_cpu;
1004+
CPUState *cpu;
10091005

10101006
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
1011-
while (cpu) {
1007+
CPU_FOREACH(cpu) {
10121008
cpu->stop = true;
10131009
qemu_cpu_kick(cpu);
1014-
cpu = cpu->next_cpu;
10151010
}
10161011

10171012
if (qemu_in_vcpu_thread()) {
10181013
cpu_stop_current();
10191014
if (!kvm_enabled()) {
1020-
cpu = first_cpu;
1021-
while (cpu) {
1015+
CPU_FOREACH(cpu) {
10221016
cpu->stop = false;
10231017
cpu->stopped = true;
1024-
cpu = cpu->next_cpu;
10251018
}
10261019
return;
10271020
}
10281021
}
10291022

10301023
while (!all_vcpus_paused()) {
10311024
qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
1032-
cpu = first_cpu;
1033-
while (cpu) {
1025+
CPU_FOREACH(cpu) {
10341026
qemu_cpu_kick(cpu);
1035-
cpu = cpu->next_cpu;
10361027
}
10371028
}
10381029
}
@@ -1046,12 +1037,11 @@ void cpu_resume(CPUState *cpu)
10461037

10471038
void resume_all_vcpus(void)
10481039
{
1049-
CPUState *cpu = first_cpu;
1040+
CPUState *cpu;
10501041

10511042
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
1052-
while (cpu) {
1043+
CPU_FOREACH(cpu) {
10531044
cpu_resume(cpu);
1054-
cpu = cpu->next_cpu;
10551045
}
10561046
}
10571047

@@ -1215,7 +1205,7 @@ static void tcg_exec_all(void)
12151205
if (next_cpu == NULL) {
12161206
next_cpu = first_cpu;
12171207
}
1218-
for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
1208+
for (; next_cpu != NULL && !exit_request; next_cpu = CPU_NEXT(next_cpu)) {
12191209
CPUState *cpu = next_cpu;
12201210
CPUArchState *env = cpu->env_ptr;
12211211

@@ -1240,7 +1230,7 @@ void set_numa_modes(void)
12401230
CPUState *cpu;
12411231
int i;
12421232

1243-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
1233+
CPU_FOREACH(cpu) {
12441234
for (i = 0; i < nb_numa_nodes; i++) {
12451235
if (test_bit(cpu->cpu_index, node_cpumask[i])) {
12461236
cpu->numa_node = i;
@@ -1262,7 +1252,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
12621252
CpuInfoList *head = NULL, *cur_item = NULL;
12631253
CPUState *cpu;
12641254

1265-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
1255+
CPU_FOREACH(cpu) {
12661256
CpuInfoList *info;
12671257
#if defined(TARGET_I386)
12681258
X86CPU *x86_cpu = X86_CPU(cpu);
@@ -1391,7 +1381,7 @@ void qmp_inject_nmi(Error **errp)
13911381
#if defined(TARGET_I386)
13921382
CPUState *cs;
13931383

1394-
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
1384+
CPU_FOREACH(cs) {
13951385
X86CPU *cpu = X86_CPU(cs);
13961386
CPUX86State *env = &cpu->env;
13971387

@@ -1405,7 +1395,7 @@ void qmp_inject_nmi(Error **errp)
14051395
CPUState *cs;
14061396
S390CPU *cpu;
14071397

1408-
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
1398+
CPU_FOREACH(cs) {
14091399
cpu = S390_CPU(cs);
14101400
if (cpu->env.cpu_num == monitor_get_cpu_index()) {
14111401
if (s390_cpu_restart(S390_CPU(cs)) == -1) {

cputlb.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length)
189189
CPUState *cpu;
190190
CPUArchState *env;
191191

192-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
192+
CPU_FOREACH(cpu) {
193193
int mmu_idx;
194194

195195
env = cpu->env_ptr;

dump.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ static int write_elf64_notes(DumpState *s)
277277
int ret;
278278
int id;
279279

280-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
280+
CPU_FOREACH(cpu) {
281281
id = cpu_index(cpu);
282282
ret = cpu_write_elf64_note(fd_write_vmcore, cpu, id, s);
283283
if (ret < 0) {
@@ -286,7 +286,7 @@ static int write_elf64_notes(DumpState *s)
286286
}
287287
}
288288

289-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
289+
CPU_FOREACH(cpu) {
290290
ret = cpu_write_elf64_qemunote(fd_write_vmcore, cpu, s);
291291
if (ret < 0) {
292292
dump_error(s, "dump: failed to write CPU status.\n");
@@ -327,7 +327,7 @@ static int write_elf32_notes(DumpState *s)
327327
int ret;
328328
int id;
329329

330-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
330+
CPU_FOREACH(cpu) {
331331
id = cpu_index(cpu);
332332
ret = cpu_write_elf32_note(fd_write_vmcore, cpu, id, s);
333333
if (ret < 0) {
@@ -336,7 +336,7 @@ static int write_elf32_notes(DumpState *s)
336336
}
337337
}
338338

339-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
339+
CPU_FOREACH(cpu) {
340340
ret = cpu_write_elf32_qemunote(fd_write_vmcore, cpu, s);
341341
if (ret < 0) {
342342
dump_error(s, "dump: failed to write CPU status.\n");
@@ -734,7 +734,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
734734
*/
735735
cpu_synchronize_all_states();
736736
nr_cpus = 0;
737-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
737+
CPU_FOREACH(cpu) {
738738
nr_cpus++;
739739
}
740740

exec.c

+9-24
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static MemoryRegion io_mem_unassigned;
6969

7070
#endif
7171

72-
CPUState *first_cpu;
72+
struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
7373
/* current CPU in the current thread. It is only valid inside
7474
cpu_exec() */
7575
DEFINE_TLS(CPUState *, current_cpu);
@@ -351,44 +351,29 @@ const VMStateDescription vmstate_cpu_common = {
351351

352352
CPUState *qemu_get_cpu(int index)
353353
{
354-
CPUState *cpu = first_cpu;
354+
CPUState *cpu;
355355

356-
while (cpu) {
356+
CPU_FOREACH(cpu) {
357357
if (cpu->cpu_index == index) {
358-
break;
358+
return cpu;
359359
}
360-
cpu = cpu->next_cpu;
361360
}
362361

363-
return cpu;
364-
}
365-
366-
void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data)
367-
{
368-
CPUState *cpu;
369-
370-
cpu = first_cpu;
371-
while (cpu) {
372-
func(cpu, data);
373-
cpu = cpu->next_cpu;
374-
}
362+
return NULL;
375363
}
376364

377365
void cpu_exec_init(CPUArchState *env)
378366
{
379367
CPUState *cpu = ENV_GET_CPU(env);
380368
CPUClass *cc = CPU_GET_CLASS(cpu);
381-
CPUState **pcpu;
369+
CPUState *some_cpu;
382370
int cpu_index;
383371

384372
#if defined(CONFIG_USER_ONLY)
385373
cpu_list_lock();
386374
#endif
387-
cpu->next_cpu = NULL;
388-
pcpu = &first_cpu;
389375
cpu_index = 0;
390-
while (*pcpu != NULL) {
391-
pcpu = &(*pcpu)->next_cpu;
376+
CPU_FOREACH(some_cpu) {
392377
cpu_index++;
393378
}
394379
cpu->cpu_index = cpu_index;
@@ -398,7 +383,7 @@ void cpu_exec_init(CPUArchState *env)
398383
#ifndef CONFIG_USER_ONLY
399384
cpu->thread_id = qemu_get_thread_id();
400385
#endif
401-
*pcpu = cpu;
386+
QTAILQ_INSERT_TAIL(&cpus, cpu, node);
402387
#if defined(CONFIG_USER_ONLY)
403388
cpu_list_unlock();
404389
#endif
@@ -1762,7 +1747,7 @@ static void tcg_commit(MemoryListener *listener)
17621747
/* since each CPU stores ram addresses in its TLB cache, we must
17631748
reset the modified entries */
17641749
/* XXX: slow ! */
1765-
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
1750+
CPU_FOREACH(cpu) {
17661751
CPUArchState *env = cpu->env_ptr;
17671752

17681753
tlb_flush(env, 1);

0 commit comments

Comments
 (0)