[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 14/16] cpus-common: Introduce async_safe_run_on_
From: |
Alex Bennée |
Subject: |
Re: [Qemu-devel] [PATCH 14/16] cpus-common: Introduce async_safe_run_on_cpu() |
Date: |
Mon, 26 Sep 2016 09:28:19 +0100 |
User-agent: |
mu4e 0.9.17; emacs 25.1.50.1 |
Paolo Bonzini <address@hidden> writes:
> Signed-off-by: Paolo Bonzini <address@hidden>
Reviewed-by: Alex Bennée <address@hidden>
> ---
> cpus-common.c | 33 +++++++++++++++++++++++++++++++--
> include/qom/cpu.h | 14 ++++++++++++++
> 2 files changed, 45 insertions(+), 2 deletions(-)
>
> diff --git a/cpus-common.c b/cpus-common.c
> index 429652c..38b1d55 100644
> --- a/cpus-common.c
> +++ b/cpus-common.c
> @@ -18,6 +18,7 @@
> */
>
> #include "qemu/osdep.h"
> +#include "qemu/main-loop.h"
> #include "exec/cpu-common.h"
> #include "qom/cpu.h"
> #include "sysemu/cpus.h"
> @@ -106,7 +107,7 @@ struct qemu_work_item {
> struct qemu_work_item *next;
> run_on_cpu_func func;
> void *data;
> - bool free, done;
> + bool free, exclusive, done;
> };
>
> static void queue_work_on_cpu(CPUState *cpu, struct qemu_work_item *wi)
> @@ -139,6 +140,7 @@ void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func,
> void *data,
> wi.data = data;
> wi.done = false;
> wi.free = false;
> + wi.exclusive = false;
>
> queue_work_on_cpu(cpu, &wi);
> while (!atomic_mb_read(&wi.done)) {
> @@ -229,6 +231,19 @@ void cpu_exec_end(CPUState *cpu)
> qemu_mutex_unlock(&qemu_cpu_list_lock);
> }
>
> +void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func, void *data)
> +{
> + struct qemu_work_item *wi;
> +
> + wi = g_malloc0(sizeof(struct qemu_work_item));
> + wi->func = func;
> + wi->data = data;
> + wi->free = true;
> + wi->exclusive = true;
> +
> + queue_work_on_cpu(cpu, wi);
> +}
> +
> void process_queued_cpu_work(CPUState *cpu)
> {
> struct qemu_work_item *wi;
> @@ -245,7 +260,21 @@ void process_queued_cpu_work(CPUState *cpu)
> cpu->queued_work_last = NULL;
> }
> qemu_mutex_unlock(&cpu->work_mutex);
> - wi->func(cpu, wi->data);
> + if (wi->exclusive) {
> + /* Running work items outside the BQL avoids the following
> deadlock:
> + * 1) start_exclusive() is called with the BQL taken while
> another
> + * CPU is running; 2) cpu_exec in the other CPU tries to takes
> the
> + * BQL, so it goes to sleep; start_exclusive() is sleeping too,
> so
> + * neither CPU can proceed.
> + */
> + qemu_mutex_unlock_iothread();
> + start_exclusive();
> + wi->func(cpu, wi->data);
> + end_exclusive();
> + qemu_mutex_lock_iothread();
> + } else {
> + wi->func(cpu, wi->data);
> + }
> qemu_mutex_lock(&cpu->work_mutex);
> if (wi->free) {
> g_free(wi);
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 934c07a..4092dd9 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -656,6 +656,20 @@ void run_on_cpu(CPUState *cpu, run_on_cpu_func func,
> void *data);
> void async_run_on_cpu(CPUState *cpu, run_on_cpu_func func, void *data);
>
> /**
> + * async_safe_run_on_cpu:
> + * @cpu: The vCPU to run on.
> + * @func: The function to be executed.
> + * @data: Data to pass to the function.
> + *
> + * Schedules the function @func for execution on the vCPU @cpu
> asynchronously,
> + * while all other vCPUs are sleeping.
> + *
> + * Unlike run_on_cpu and async_run_on_cpu, the function is run outside the
> + * BQL.
> + */
> +void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func, void *data);
> +
> +/**
> * qemu_get_cpu:
> * @index: The address@hidden value of the CPU to obtain.
> *
--
Alex Bennée
- [Qemu-devel] [PATCH 13/16] cpus-common: simplify locking for start_exclusive/end_exclusive, (continued)
[Qemu-devel] [PATCH 14/16] cpus-common: Introduce async_safe_run_on_cpu(), Paolo Bonzini, 2016/09/23
[Qemu-devel] [PATCH 16/16] cpus-common: lock-free fast path for cpu_exec_start/end, Paolo Bonzini, 2016/09/23
- Re: [Qemu-devel] [PATCH 16/16] cpus-common: lock-free fast path for cpu_exec_start/end, Richard Henderson, 2016/09/23
- Re: [Qemu-devel] [PATCH 16/16] cpus-common: lock-free fast path for cpu_exec_start/end, Paolo Bonzini, 2016/09/24
- Re: [Qemu-devel] [PATCH 16/16] cpus-common: lock-free fast path for cpu_exec_start/end, Richard Henderson, 2016/09/24
- Re: [Qemu-devel] [PATCH 16/16] cpus-common: lock-free fast path for cpu_exec_start/end, Paolo Bonzini, 2016/09/26
- Re: [Qemu-devel] [PATCH 16/16] cpus-common: lock-free fast path for cpu_exec_start/end, Alex Bennée, 2016/09/26
- Re: [Qemu-devel] [PATCH 16/16] cpus-common: lock-free fast path for cpu_exec_start/end, Paolo Bonzini, 2016/09/26
[Qemu-devel] [PATCH 12/16] cpus-common: remove redundant call to exclusive_idle(), Paolo Bonzini, 2016/09/23