cpu: move Qemu[Thread|Cond] setup into common code
Aside from the round robin threads this is all common code. By moving the halt_cond setup we also no longer need hacks to work around the race between QOM object creation and thread creation. It is a little ugly to free stuff up for the round robin thread but better it deal with its own specialises than making the other accelerators jump through hoops. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Message-ID: <20240530194250.1801701-3-alex.bennee@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
This commit is contained in:
		
				
					committed by
					
						
						Philippe Mathieu-Daudé
					
				
			
			
				
	
			
			
			
						parent
						
							b8a208ccf5
						
					
				
				
					commit
					a4c2735f35
				
			@@ -68,9 +68,6 @@ void dummy_start_vcpu_thread(CPUState *cpu)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    char thread_name[VCPU_THREAD_NAME_SIZE];
 | 
					    char thread_name[VCPU_THREAD_NAME_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu->thread = g_malloc0(sizeof(QemuThread));
 | 
					 | 
				
			||||||
    cpu->halt_cond = g_malloc0(sizeof(QemuCond));
 | 
					 | 
				
			||||||
    qemu_cond_init(cpu->halt_cond);
 | 
					 | 
				
			||||||
    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/DUMMY",
 | 
					    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/DUMMY",
 | 
				
			||||||
             cpu->cpu_index);
 | 
					             cpu->cpu_index);
 | 
				
			||||||
    qemu_thread_create(cpu->thread, thread_name, dummy_cpu_thread_fn, cpu,
 | 
					    qemu_thread_create(cpu->thread, thread_name, dummy_cpu_thread_fn, cpu,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -463,10 +463,6 @@ static void hvf_start_vcpu_thread(CPUState *cpu)
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    assert(hvf_enabled());
 | 
					    assert(hvf_enabled());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu->thread = g_malloc0(sizeof(QemuThread));
 | 
					 | 
				
			||||||
    cpu->halt_cond = g_malloc0(sizeof(QemuCond));
 | 
					 | 
				
			||||||
    qemu_cond_init(cpu->halt_cond);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HVF",
 | 
					    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HVF",
 | 
				
			||||||
             cpu->cpu_index);
 | 
					             cpu->cpu_index);
 | 
				
			||||||
    qemu_thread_create(cpu->thread, thread_name, hvf_cpu_thread_fn,
 | 
					    qemu_thread_create(cpu->thread, thread_name, hvf_cpu_thread_fn,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,9 +66,6 @@ static void kvm_start_vcpu_thread(CPUState *cpu)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    char thread_name[VCPU_THREAD_NAME_SIZE];
 | 
					    char thread_name[VCPU_THREAD_NAME_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu->thread = g_malloc0(sizeof(QemuThread));
 | 
					 | 
				
			||||||
    cpu->halt_cond = g_malloc0(sizeof(QemuCond));
 | 
					 | 
				
			||||||
    qemu_cond_init(cpu->halt_cond);
 | 
					 | 
				
			||||||
    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/KVM",
 | 
					    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/KVM",
 | 
				
			||||||
             cpu->cpu_index);
 | 
					             cpu->cpu_index);
 | 
				
			||||||
    qemu_thread_create(cpu->thread, thread_name, kvm_vcpu_thread_fn,
 | 
					    qemu_thread_create(cpu->thread, thread_name, kvm_vcpu_thread_fn,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -137,10 +137,6 @@ void mttcg_start_vcpu_thread(CPUState *cpu)
 | 
				
			|||||||
    g_assert(tcg_enabled());
 | 
					    g_assert(tcg_enabled());
 | 
				
			||||||
    tcg_cpu_init_cflags(cpu, current_machine->smp.max_cpus > 1);
 | 
					    tcg_cpu_init_cflags(cpu, current_machine->smp.max_cpus > 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu->thread = g_new0(QemuThread, 1);
 | 
					 | 
				
			||||||
    cpu->halt_cond = g_malloc0(sizeof(QemuCond));
 | 
					 | 
				
			||||||
    qemu_cond_init(cpu->halt_cond);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* create a thread per vCPU with TCG (MTTCG) */
 | 
					    /* create a thread per vCPU with TCG (MTTCG) */
 | 
				
			||||||
    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",
 | 
					    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",
 | 
				
			||||||
             cpu->cpu_index);
 | 
					             cpu->cpu_index);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -317,22 +317,22 @@ void rr_start_vcpu_thread(CPUState *cpu)
 | 
				
			|||||||
    tcg_cpu_init_cflags(cpu, false);
 | 
					    tcg_cpu_init_cflags(cpu, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!single_tcg_cpu_thread) {
 | 
					    if (!single_tcg_cpu_thread) {
 | 
				
			||||||
        cpu->thread = g_new0(QemuThread, 1);
 | 
					        single_tcg_halt_cond = cpu->halt_cond;
 | 
				
			||||||
        cpu->halt_cond = g_new0(QemuCond, 1);
 | 
					        single_tcg_cpu_thread = cpu->thread;
 | 
				
			||||||
        qemu_cond_init(cpu->halt_cond);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* share a single thread for all cpus with TCG */
 | 
					        /* share a single thread for all cpus with TCG */
 | 
				
			||||||
        snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "ALL CPUs/TCG");
 | 
					        snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "ALL CPUs/TCG");
 | 
				
			||||||
        qemu_thread_create(cpu->thread, thread_name,
 | 
					        qemu_thread_create(cpu->thread, thread_name,
 | 
				
			||||||
                           rr_cpu_thread_fn,
 | 
					                           rr_cpu_thread_fn,
 | 
				
			||||||
                           cpu, QEMU_THREAD_JOINABLE);
 | 
					                           cpu, QEMU_THREAD_JOINABLE);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        single_tcg_halt_cond = cpu->halt_cond;
 | 
					 | 
				
			||||||
        single_tcg_cpu_thread = cpu->thread;
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        /* we share the thread */
 | 
					        /* we share the thread, dump spare data */
 | 
				
			||||||
 | 
					        g_free(cpu->thread);
 | 
				
			||||||
 | 
					        qemu_cond_destroy(cpu->halt_cond);
 | 
				
			||||||
        cpu->thread = single_tcg_cpu_thread;
 | 
					        cpu->thread = single_tcg_cpu_thread;
 | 
				
			||||||
        cpu->halt_cond = single_tcg_halt_cond;
 | 
					        cpu->halt_cond = single_tcg_halt_cond;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* copy the stuff done at start of rr_cpu_thread_fn */
 | 
				
			||||||
        cpu->thread_id = first_cpu->thread_id;
 | 
					        cpu->thread_id = first_cpu->thread_id;
 | 
				
			||||||
        cpu->neg.can_do_io = 1;
 | 
					        cpu->neg.can_do_io = 1;
 | 
				
			||||||
        cpu->created = true;
 | 
					        cpu->created = true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -261,6 +261,11 @@ static void cpu_common_initfn(Object *obj)
 | 
				
			|||||||
    cpu->nr_threads = 1;
 | 
					    cpu->nr_threads = 1;
 | 
				
			||||||
    cpu->cflags_next_tb = -1;
 | 
					    cpu->cflags_next_tb = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* allocate storage for thread info, initialise condition variables */
 | 
				
			||||||
 | 
					    cpu->thread = g_new0(QemuThread, 1);
 | 
				
			||||||
 | 
					    cpu->halt_cond = g_new0(QemuCond, 1);
 | 
				
			||||||
 | 
					    qemu_cond_init(cpu->halt_cond);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_mutex_init(&cpu->work_mutex);
 | 
					    qemu_mutex_init(&cpu->work_mutex);
 | 
				
			||||||
    qemu_lockcnt_init(&cpu->in_ioctl_lock);
 | 
					    qemu_lockcnt_init(&cpu->in_ioctl_lock);
 | 
				
			||||||
    QSIMPLEQ_INIT(&cpu->work_list);
 | 
					    QSIMPLEQ_INIT(&cpu->work_list);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -404,10 +404,14 @@ struct qemu_work_item;
 | 
				
			|||||||
 * @tcg_cflags: Pre-computed cflags for this cpu.
 | 
					 * @tcg_cflags: Pre-computed cflags for this cpu.
 | 
				
			||||||
 * @nr_cores: Number of cores within this CPU package.
 | 
					 * @nr_cores: Number of cores within this CPU package.
 | 
				
			||||||
 * @nr_threads: Number of threads within this CPU core.
 | 
					 * @nr_threads: Number of threads within this CPU core.
 | 
				
			||||||
 | 
					 * @thread: Host thread details, only live once @created is #true
 | 
				
			||||||
 | 
					 * @sem: WIN32 only semaphore used only for qtest
 | 
				
			||||||
 | 
					 * @thread_id: native thread id of vCPU, only live once @created is #true
 | 
				
			||||||
 * @running: #true if CPU is currently running (lockless).
 | 
					 * @running: #true if CPU is currently running (lockless).
 | 
				
			||||||
 * @has_waiter: #true if a CPU is currently waiting for the cpu_exec_end;
 | 
					 * @has_waiter: #true if a CPU is currently waiting for the cpu_exec_end;
 | 
				
			||||||
 * valid under cpu_list_lock.
 | 
					 * valid under cpu_list_lock.
 | 
				
			||||||
 * @created: Indicates whether the CPU thread has been successfully created.
 | 
					 * @created: Indicates whether the CPU thread has been successfully created.
 | 
				
			||||||
 | 
					 * @halt_cond: condition variable sleeping threads can wait on.
 | 
				
			||||||
 * @interrupt_request: Indicates a pending interrupt request.
 | 
					 * @interrupt_request: Indicates a pending interrupt request.
 | 
				
			||||||
 * @halted: Nonzero if the CPU is in suspended state.
 | 
					 * @halted: Nonzero if the CPU is in suspended state.
 | 
				
			||||||
 * @stop: Indicates a pending stop request.
 | 
					 * @stop: Indicates a pending stop request.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,9 +64,6 @@ static void nvmm_start_vcpu_thread(CPUState *cpu)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    char thread_name[VCPU_THREAD_NAME_SIZE];
 | 
					    char thread_name[VCPU_THREAD_NAME_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu->thread = g_new0(QemuThread, 1);
 | 
					 | 
				
			||||||
    cpu->halt_cond = g_new0(QemuCond, 1);
 | 
					 | 
				
			||||||
    qemu_cond_init(cpu->halt_cond);
 | 
					 | 
				
			||||||
    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/NVMM",
 | 
					    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/NVMM",
 | 
				
			||||||
             cpu->cpu_index);
 | 
					             cpu->cpu_index);
 | 
				
			||||||
    qemu_thread_create(cpu->thread, thread_name, qemu_nvmm_cpu_thread_fn,
 | 
					    qemu_thread_create(cpu->thread, thread_name, qemu_nvmm_cpu_thread_fn,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,9 +64,6 @@ static void whpx_start_vcpu_thread(CPUState *cpu)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    char thread_name[VCPU_THREAD_NAME_SIZE];
 | 
					    char thread_name[VCPU_THREAD_NAME_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu->thread = g_new0(QemuThread, 1);
 | 
					 | 
				
			||||||
    cpu->halt_cond = g_new0(QemuCond, 1);
 | 
					 | 
				
			||||||
    qemu_cond_init(cpu->halt_cond);
 | 
					 | 
				
			||||||
    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/WHPX",
 | 
					    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/WHPX",
 | 
				
			||||||
             cpu->cpu_index);
 | 
					             cpu->cpu_index);
 | 
				
			||||||
    qemu_thread_create(cpu->thread, thread_name, whpx_cpu_thread_fn,
 | 
					    qemu_thread_create(cpu->thread, thread_name, whpx_cpu_thread_fn,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user