qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC v4 20/28] cpus: tweak sleeping and safe_work rules


From: Paolo Bonzini
Subject: Re: [Qemu-devel] [RFC v4 20/28] cpus: tweak sleeping and safe_work rules for MTTCG
Date: Wed, 7 Sep 2016 12:05:36 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0


On 11/08/2016 17:24, Alex Bennée wrote:
> Once TCG gains the ability to sleep individual threads we need to make
> sure they don't sleep when safe work is pending as all threads need to
> go through the process_queued_work function. Also if we have multiple
> threads wait_for_safe_work can now sleep without deadlocking.
> 
> Signed-off-by: Alex Bennée <address@hidden>
> 
> ---
> v4
>   - new for v4, ontop of async-safe-work-v5
> ---
>  cpu-exec-common.c | 15 ++++++++++++++-
>  cpus.c            |  2 +-
>  include/qom/cpu.h |  8 ++++++++
>  3 files changed, 23 insertions(+), 2 deletions(-)
> 
> diff --git a/cpu-exec-common.c b/cpu-exec-common.c
> index e29cf6d..84cb789 100644
> --- a/cpu-exec-common.c
> +++ b/cpu-exec-common.c
> @@ -83,6 +83,18 @@ QemuCond qemu_exclusive_cond;
>  
>  static int safe_work_pending;
>  
> +/* No vCPUs can sleep while there is safe work pending as we need
> + * everything to finish up in process_cpu_work.
> + */
> +bool cpu_has_queued_work(CPUState *cpu)
> +{
> +    if (cpu->queued_work || atomic_mb_read(&safe_work_pending) > 0) {
> +        return true;
> +    } else {
> +        return false;
> +    }
> +}

This should not be needed anymore with the new version.  If a safe work
item is pending, its CPU will have cpu->queued_work != NULL.  The work
item will then run as soon as the CPU is scheduled because no other CPUs
can be inside TCG.

Paolo

>  #ifdef CONFIG_USER_ONLY
>  #define can_wait_for_safe() (1)
>  #else
> @@ -91,7 +103,8 @@ static int safe_work_pending;
>   * all vCPUs are in the same thread. This will change for MTTCG
>   * however.
>   */
> -#define can_wait_for_safe() (0)
> +extern int smp_cpus;
> +#define can_wait_for_safe() (mttcg_enabled && smp_cpus > 1)
>  #endif
>  
>  void wait_safe_cpu_work(void)
> diff --git a/cpus.c b/cpus.c
> index 8a40a08..4fc5e4c 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -88,7 +88,7 @@ bool cpu_is_stopped(CPUState *cpu)
>  
>  static bool cpu_thread_is_idle(CPUState *cpu)
>  {
> -    if (cpu->stop || cpu->queued_work) {
> +    if (cpu->stop || cpu_has_queued_work(cpu)) {
>          return false;
>      }
>      if (cpu_is_stopped(cpu)) {
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 5ecbd29..d0db846 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -661,6 +661,14 @@ void async_run_on_cpu(CPUState *cpu, run_on_cpu_func 
> func, void *data);
>  void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func, void *data);
>  
>  /**
> + * cpu_has_queued_work:
> + * @cpu: The vCPU to check
> + *
> + * Returns true if there is *_run_on_cpu work to be done.
> + */
> +bool cpu_has_queued_work(CPUState *cpu);
> +
> +/**
>   * qemu_get_cpu:
>   * @index: The address@hidden value of the CPU to obtain.
>   *
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]