Commit aaa6a401 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

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
parents bb7d4d82 5e891bf8
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -1196,15 +1196,14 @@ static void mig_sleep_cpu(void *opq)
   much time in the VM. The migration thread will try to catchup.
   Workload will experience a performance drop.
*/
static void mig_throttle_cpu_down(CPUState *cpu, void *data)
{
    async_run_on_cpu(cpu, mig_sleep_cpu, NULL);
}

static void mig_throttle_guest_down(void)
{
    CPUState *cpu;

    qemu_mutex_lock_iothread();
    qemu_for_each_cpu(mig_throttle_cpu_down, NULL);
    CPU_FOREACH(cpu) {
        async_run_on_cpu(cpu, mig_sleep_cpu, NULL);
    }
    qemu_mutex_unlock_iothread();
}

+25 −35
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ static bool all_cpu_threads_idle(void)
{
    CPUState *cpu;

    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
    CPU_FOREACH(cpu) {
        if (!cpu_thread_is_idle(cpu)) {
            return false;
        }
@@ -416,7 +416,7 @@ void hw_error(const char *fmt, ...)
    fprintf(stderr, "qemu: hardware error: ");
    vfprintf(stderr, fmt, ap);
    fprintf(stderr, "\n");
    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
    CPU_FOREACH(cpu) {
        fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
        cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU);
    }
@@ -428,7 +428,7 @@ void cpu_synchronize_all_states(void)
{
    CPUState *cpu;

    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
    CPU_FOREACH(cpu) {
        cpu_synchronize_state(cpu);
    }
}
@@ -437,7 +437,7 @@ void cpu_synchronize_all_post_reset(void)
{
    CPUState *cpu;

    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
    CPU_FOREACH(cpu) {
        cpu_synchronize_post_reset(cpu);
    }
}
@@ -446,7 +446,7 @@ void cpu_synchronize_all_post_init(void)
{
    CPUState *cpu;

    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
    CPU_FOREACH(cpu) {
        cpu_synchronize_post_init(cpu);
    }
}
@@ -760,7 +760,7 @@ static void qemu_tcg_wait_io_event(void)
        qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
    }

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

static void tcg_exec_all(void);

static void tcg_signal_cpu_creation(CPUState *cpu, void *data)
{
    cpu->thread_id = qemu_get_thread_id();
    cpu->created = true;
}

static void *qemu_tcg_cpu_thread_fn(void *arg)
{
    CPUState *cpu = arg;
@@ -868,15 +862,18 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
    qemu_thread_get_self(cpu->thread);

    qemu_mutex_lock(&qemu_global_mutex);
    qemu_for_each_cpu(tcg_signal_cpu_creation, NULL);
    CPU_FOREACH(cpu) {
        cpu->thread_id = qemu_get_thread_id();
        cpu->created = true;
    }
    qemu_cond_signal(&qemu_cpu_cond);

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

        /* process any pending work */
        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
        CPU_FOREACH(cpu) {
            qemu_wait_io_event_common(cpu);
        }
    }
@@ -991,13 +988,12 @@ void qemu_mutex_unlock_iothread(void)

static int all_vcpus_paused(void)
{
    CPUState *cpu = first_cpu;
    CPUState *cpu;

    while (cpu) {
    CPU_FOREACH(cpu) {
        if (!cpu->stopped) {
            return 0;
        }
        cpu = cpu->next_cpu;
    }

    return 1;
@@ -1005,23 +1001,20 @@ static int all_vcpus_paused(void)

void pause_all_vcpus(void)
{
    CPUState *cpu = first_cpu;
    CPUState *cpu;

    qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
    while (cpu) {
    CPU_FOREACH(cpu) {
        cpu->stop = true;
        qemu_cpu_kick(cpu);
        cpu = cpu->next_cpu;
    }

    if (qemu_in_vcpu_thread()) {
        cpu_stop_current();
        if (!kvm_enabled()) {
            cpu = first_cpu;
            while (cpu) {
            CPU_FOREACH(cpu) {
                cpu->stop = false;
                cpu->stopped = true;
                cpu = cpu->next_cpu;
            }
            return;
        }
@@ -1029,10 +1022,8 @@ void pause_all_vcpus(void)

    while (!all_vcpus_paused()) {
        qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
        cpu = first_cpu;
        while (cpu) {
        CPU_FOREACH(cpu) {
            qemu_cpu_kick(cpu);
            cpu = cpu->next_cpu;
        }
    }
}
@@ -1046,12 +1037,11 @@ void cpu_resume(CPUState *cpu)

void resume_all_vcpus(void)
{
    CPUState *cpu = first_cpu;
    CPUState *cpu;

    qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
    while (cpu) {
    CPU_FOREACH(cpu) {
        cpu_resume(cpu);
        cpu = cpu->next_cpu;
    }
}

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

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

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

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

    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
    CPU_FOREACH(cs) {
        X86CPU *cpu = X86_CPU(cs);
        CPUX86State *env = &cpu->env;

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

    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
    CPU_FOREACH(cs) {
        cpu = S390_CPU(cs);
        if (cpu->env.cpu_num == monitor_get_cpu_index()) {
            if (s390_cpu_restart(S390_CPU(cs)) == -1) {
+1 −1
Original line number Diff line number Diff line
@@ -189,7 +189,7 @@ void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length)
    CPUState *cpu;
    CPUArchState *env;

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

        env = cpu->env_ptr;
+5 −5
Original line number Diff line number Diff line
@@ -277,7 +277,7 @@ static int write_elf64_notes(DumpState *s)
    int ret;
    int id;

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

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

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

    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
    CPU_FOREACH(cpu) {
        ret = cpu_write_elf32_qemunote(fd_write_vmcore, cpu, s);
        if (ret < 0) {
            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,
     */
    cpu_synchronize_all_states();
    nr_cpus = 0;
    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
    CPU_FOREACH(cpu) {
        nr_cpus++;
    }

+9 −24
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ static MemoryRegion io_mem_unassigned;

#endif

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

CPUState *qemu_get_cpu(int index)
{
    CPUState *cpu = first_cpu;
    CPUState *cpu;

    while (cpu) {
    CPU_FOREACH(cpu) {
        if (cpu->cpu_index == index) {
            break;
        }
        cpu = cpu->next_cpu;
    }

            return cpu;
        }

void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data)
{
    CPUState *cpu;

    cpu = first_cpu;
    while (cpu) {
        func(cpu, data);
        cpu = cpu->next_cpu;
    }

    return NULL;
}

void cpu_exec_init(CPUArchState *env)
{
    CPUState *cpu = ENV_GET_CPU(env);
    CPUClass *cc = CPU_GET_CLASS(cpu);
    CPUState **pcpu;
    CPUState *some_cpu;
    int cpu_index;

#if defined(CONFIG_USER_ONLY)
    cpu_list_lock();
#endif
    cpu->next_cpu = NULL;
    pcpu = &first_cpu;
    cpu_index = 0;
    while (*pcpu != NULL) {
        pcpu = &(*pcpu)->next_cpu;
    CPU_FOREACH(some_cpu) {
        cpu_index++;
    }
    cpu->cpu_index = cpu_index;
@@ -398,7 +383,7 @@ void cpu_exec_init(CPUArchState *env)
#ifndef CONFIG_USER_ONLY
    cpu->thread_id = qemu_get_thread_id();
#endif
    *pcpu = cpu;
    QTAILQ_INSERT_TAIL(&cpus, cpu, node);
#if defined(CONFIG_USER_ONLY)
    cpu_list_unlock();
#endif
@@ -1762,7 +1747,7 @@ static void tcg_commit(MemoryListener *listener)
    /* since each CPU stores ram addresses in its TLB cache, we must
       reset the modified entries */
    /* XXX: slow ! */
    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
    CPU_FOREACH(cpu) {
        CPUArchState *env = cpu->env_ptr;

        tlb_flush(env, 1);
Loading