[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 10/12] cpus-common: Introduce async_safe_run_on_
From: |
Alex Bennée |
Subject: |
Re: [Qemu-devel] [PATCH 10/12] cpus-common: Introduce async_safe_run_on_cpu() |
Date: |
Mon, 05 Sep 2016 16:41:23 +0100 |
User-agent: |
mu4e 0.9.17; emacs 25.1.11 |
Paolo Bonzini <address@hidden> writes:
> On 05/09/2016 17:08, Alex Bennée wrote:
>>
>> Paolo Bonzini <address@hidden> writes:
>>
>>> Signed-off-by: Paolo Bonzini <address@hidden>
>>> ---
>>> cpus-common.c | 25 +++++++++++++++++++++++++
>>> include/qom/cpu.h | 12 ++++++++++++
>>> 2 files changed, 37 insertions(+)
>>>
>>> diff --git a/cpus-common.c b/cpus-common.c
>>> index 59c8dc8..88cf5ec 100644
>>> --- a/cpus-common.c
>>> +++ b/cpus-common.c
>>> @@ -144,6 +144,11 @@ void async_run_on_cpu(CPUState *cpu, run_on_cpu_func
>>> func, void *data)
>>> queue_work_on_cpu(cpu, wi);
>>> }
>>>
>>> +typedef struct SafeWorkItem {
>>> + run_on_cpu_func func;
>>> + void *data;
>>> +} SafeWorkItem;
>>> +
>>> /* Wait for pending exclusive operations to complete. The exclusive lock
>>> must be held. */
>>> static inline void exclusive_idle(void)
>>> @@ -208,6 +213,26 @@ void cpu_exec_end(CPUState *cpu)
>>> qemu_mutex_unlock(&qemu_cpu_list_mutex);
>>> }
>>>
>>> +static void async_safe_run_on_cpu_fn(CPUState *cpu, void *data)
>>> +{
>>> + SafeWorkItem *w = data;
>>> +
>>> + start_exclusive();
>>> + w->func(cpu, w->data);
>>> + end_exclusive();
>>> + g_free(w);
>>> +}
>>> +
>>> +void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func, void *data)
>>> +{
>>> + SafeWorkItem *w = g_new(SafeWorkItem, 1);
>>
>> OK so I appreciate this approach is a neat way to embed safe work in the
>> existing queue but does it really offer that much more for yet another
>> dynamic allocation vs an extra flag to the WorkItem?
>
> Actually I had it that way in the "first version" (the one that I
> promised last Monday). The questions are:
>
> 1) is it so different to have 1 vs. 2 mini allocations
>
> 2) is this a fast path
>
> but it's no big deal, I can certainly change back.
When the system is under stress it all adds up - but as I said the test
case was a fairly special. Keeping it all in one structure does make it
easier to convert to an array later though.
I'll see if I can come up with a differently pathological case and I'll
benchmark the two approaches.
>
> Paolo
>
>> In previous iterations I can DoS QEMU with a guest that does heavy
>> cross-CPU TLB flushing which led to a storm of mini allocations (for the
>> list and associated structures). This caused the massive memory usage as
>> the queue backed up.
>>
>> I appreciate it was a fairly special test case and I introduced other
>> mitigations in the base patches cputlb code to get around it however it
>> was the driver for me experimenting with the pre-allocated array for
>> holding work items.
>>
>>> +
>>> + w->func = func;
>>> + w->data = data;
>>> +
>>> + async_run_on_cpu(cpu, async_safe_run_on_cpu_fn, w);
>>> +}
>>> +
>>> void process_queued_cpu_work(CPUState *cpu)
>>> {
>>> struct qemu_work_item *wi;
>>> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
>>> index 0e04e8f..54a875e 100644
>>> --- a/include/qom/cpu.h
>>> +++ b/include/qom/cpu.h
>>> @@ -663,6 +663,18 @@ 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. @func is called with the CPU list
>>> lock
>>> + * taken (and for system emulation the BQL); any other lock can be taken
>>> safely.
>>> + */
>>> +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
>>
--
Alex Bennée
- Re: [Qemu-devel] [PATCH 06/12] cpus-common: move CPU list management to common code, (continued)
- [Qemu-devel] [PATCH 12/12] cpus-common: lock-free fast path for cpu_exec_start/end, Paolo Bonzini, 2016/09/01
- [Qemu-devel] [PATCH 11/12] tcg: Make tb_flush() thread safe, Paolo Bonzini, 2016/09/01
- [Qemu-devel] [PATCH 09/12] cpus-common: always defer async_run_on_cpu work items, Paolo Bonzini, 2016/09/01
- [Qemu-devel] [PATCH 10/12] cpus-common: Introduce async_safe_run_on_cpu(), Paolo Bonzini, 2016/09/01
- Re: [Qemu-devel] [PATCH 10/12] cpus-common: Introduce async_safe_run_on_cpu(), Pranith Kumar, 2016/09/12
- Re: [Qemu-devel] [PATCH v6 00/12] cpu-exec: Safe work in quiescent state, Alex Bennée, 2016/09/05