All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frederic Konrad <fred.konrad@greensocs.com>
To: Paolo Bonzini <pbonzini@redhat.com>, qemu-devel@nongnu.org
Cc: mttcg@greensocs.com
Subject: Re: [Qemu-devel] [PATCH 03/10] replace spinlock by QemuMutex.
Date: Thu, 13 Aug 2015 14:17:35 +0200	[thread overview]
Message-ID: <55CC8ADF.6040002@greensocs.com> (raw)
In-Reply-To: <1439397664-70734-4-git-send-email-pbonzini@redhat.com>

On 12/08/2015 18:40, Paolo Bonzini wrote:
> From: KONRAD Frederic <fred.konrad@greensocs.com>
>
> spinlock is only used in two cases:
>    * cpu-exec.c: to protect TranslationBlock
>    * mem_helper.c: for lock helper in target-i386 (which seems broken).
>
> It's a pthread_mutex_t in user-mode so better using QemuMutex directly in this
> case.
> It allows as well to reuse tb_lock mutex of TBContext in case of multithread
> TCG.
>
> Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
> Message-Id: <1439220437-23957-5-git-send-email-fred.konrad@greensocs.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   cpu-exec.c               | 15 +++------------
>   include/exec/exec-all.h  |  4 ++--
>   linux-user/main.c        |  6 +++---
>   target-i386/cpu.h        |  3 +++
>   target-i386/mem_helper.c | 25 ++++++++++++++++++++++---
>   target-i386/translate.c  |  2 ++
>   tcg/tcg.h                |  4 ++++
>   translate-all.c          | 34 ++++++++++++++++++++++++++++++++++
>   8 files changed, 73 insertions(+), 20 deletions(-)
>
> diff --git a/cpu-exec.c b/cpu-exec.c
> index 713540f..c680cca 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -356,9 +356,6 @@ int cpu_exec(CPUState *cpu)
>       uintptr_t next_tb;
>       SyncClocks sc;
>   
> -    /* This must be volatile so it is not trashed by longjmp() */
> -    volatile bool have_tb_lock = false;
> -
>       if (cpu->halted) {
>           if (!cpu_has_work(cpu)) {
>               return EXCP_HALTED;
> @@ -475,8 +472,7 @@ int cpu_exec(CPUState *cpu)
>                       cpu->exception_index = EXCP_INTERRUPT;
>                       cpu_loop_exit(cpu);
>                   }
> -                spin_lock(&tcg_ctx.tb_ctx.tb_lock);
> -                have_tb_lock = true;
> +                tb_lock();
>                   tb = tb_find_fast(cpu);
>                   /* Note: we do it here to avoid a gcc bug on Mac OS X when
>                      doing it in tb_find_slow */
> @@ -498,9 +494,7 @@ int cpu_exec(CPUState *cpu)
>                       tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
>                                   next_tb & TB_EXIT_MASK, tb);
>                   }
> -                have_tb_lock = false;
> -                spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
> -
> +                tb_unlock();
>                   /* cpu_interrupt might be called while translating the
>                      TB, but before it is linked into a potentially
>                      infinite loop and becomes env->current_tb. Avoid
> @@ -567,10 +561,7 @@ int cpu_exec(CPUState *cpu)
>               x86_cpu = X86_CPU(cpu);
>               env = &x86_cpu->env;
>   #endif
> -            if (have_tb_lock) {
> -                spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
> -                have_tb_lock = false;
> -            }
> +            tb_lock_reset();
>           }
>       } /* for(;;) */
>   
> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> index 29775c0..dafd177 100644
> --- a/include/exec/exec-all.h
> +++ b/include/exec/exec-all.h
> @@ -178,7 +178,7 @@ struct TranslationBlock {
>       struct TranslationBlock *jmp_first;
>   };
>   
> -#include "exec/spinlock.h"
> +#include "qemu/thread.h"
>   
>   typedef struct TBContext TBContext;
>   
> @@ -188,7 +188,7 @@ struct TBContext {
>       TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
>       int nb_tbs;
>       /* any access to the tbs or the page table must use this lock */
> -    spinlock_t tb_lock;
> +    QemuMutex tb_lock;
>   
>       /* statistics */
>       int tb_flush_count;
> diff --git a/linux-user/main.c b/linux-user/main.c
> index fdee981..fd06ce9 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -107,7 +107,7 @@ static int pending_cpus;
>   /* Make sure everything is in a consistent state for calling fork().  */
>   void fork_start(void)
>   {
> -    pthread_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
> +    qemu_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
>       pthread_mutex_lock(&exclusive_lock);
>       mmap_fork_start();
>   }
> @@ -129,11 +129,11 @@ void fork_end(int child)
>           pthread_mutex_init(&cpu_list_mutex, NULL);
>           pthread_cond_init(&exclusive_cond, NULL);
>           pthread_cond_init(&exclusive_resume, NULL);
> -        pthread_mutex_init(&tcg_ctx.tb_ctx.tb_lock, NULL);
> +        qemu_mutex_init(&tcg_ctx.tb_ctx.tb_lock);
>           gdbserver_fork(thread_cpu);
>       } else {
>           pthread_mutex_unlock(&exclusive_lock);
> -        pthread_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
> +        qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
We might want to use tb_lock/unlock in user code as well instead of 
calling directly
qemu_mutex_* ?

>       }
>   }
>   
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index ead2832..3655ff3 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -1318,6 +1318,9 @@ static inline MemTxAttrs cpu_get_mem_attrs(CPUX86State *env)
>   void cpu_set_mxcsr(CPUX86State *env, uint32_t val);
>   void cpu_set_fpuc(CPUX86State *env, uint16_t val);
>   
> +/* mem_helper.c */
> +void helper_lock_init(void);
> +
>   /* svm_helper.c */
>   void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
>                                      uint64_t param);
> diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
> index 1aec8a5..8bf0da2 100644
> --- a/target-i386/mem_helper.c
> +++ b/target-i386/mem_helper.c
> @@ -23,18 +23,37 @@
>   
>   /* broken thread support */
>   
> -static spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
> +#if defined(CONFIG_USER_ONLY)
> +QemuMutex global_cpu_lock;
>   
>   void helper_lock(void)
>   {
> -    spin_lock(&global_cpu_lock);
> +    qemu_mutex_lock(&global_cpu_lock);
>   }
>   
>   void helper_unlock(void)
>   {
> -    spin_unlock(&global_cpu_lock);
> +    qemu_mutex_unlock(&global_cpu_lock);
>   }
>   
> +void helper_lock_init(void)
> +{
> +    qemu_mutex_init(&global_cpu_lock);
> +}
> +#else
> +void helper_lock(void)
> +{
> +}
> +
> +void helper_unlock(void)
> +{
> +}
> +
> +void helper_lock_init(void)
> +{
> +}
> +#endif
> +
>   void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
>   {
>       uint64_t d;
> diff --git a/target-i386/translate.c b/target-i386/translate.c
> index 82e2245..443bf60 100644
> --- a/target-i386/translate.c
> +++ b/target-i386/translate.c
> @@ -7899,6 +7899,8 @@ void optimize_flags_init(void)
>                                            offsetof(CPUX86State, regs[i]),
>                                            reg_names[i]);
>       }
> +
> +    helper_lock_init();
>   }
>   
>   /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
> diff --git a/tcg/tcg.h b/tcg/tcg.h
> index 231a781..0ae648f 100644
> --- a/tcg/tcg.h
> +++ b/tcg/tcg.h
> @@ -594,6 +594,10 @@ void *tcg_malloc_internal(TCGContext *s, int size);
>   void tcg_pool_reset(TCGContext *s);
>   void tcg_pool_delete(TCGContext *s);
>   
> +void tb_lock(void);
> +void tb_unlock(void);
> +void tb_lock_reset(void);
> +
>   static inline void *tcg_malloc(int size)
>   {
>       TCGContext *s = &tcg_ctx;
> diff --git a/translate-all.c b/translate-all.c
> index 9c46ffa..a6bff72 100644
> --- a/translate-all.c
> +++ b/translate-all.c
> @@ -129,6 +129,39 @@ static void *l1_map[V_L1_SIZE];
>   /* code generation context */
>   TCGContext tcg_ctx;
>   
> +/* translation block context */
> +#ifdef CONFIG_USER_ONLY
> +__thread volatile int have_tb_lock;
> +#endif
> +
> +void tb_lock(void)
> +{
> +#ifdef CONFIG_USER_ONLY
> +    assert(!have_tb_lock);
> +    qemu_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
> +    have_tb_lock++;
> +#endif
> +}
> +
> +void tb_unlock(void)
> +{
> +#ifdef CONFIG_USER_ONLY
> +    assert(have_tb_lock);
> +    have_tb_lock--;
> +    qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
> +#endif
> +}
> +
> +void tb_lock_reset(void)
> +{
> +#ifdef CONFIG_USER_ONLY
> +    if (have_tb_lock) {
> +        qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
> +        have_tb_lock = 0;
> +    }
> +#endif
> +}
> +
>   static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
>                            tb_page_addr_t phys_page2);
>   static TranslationBlock *tb_find_pc(uintptr_t tc_ptr);
> @@ -676,6 +709,7 @@ static inline void code_gen_alloc(size_t tb_size)
>               CODE_GEN_AVG_BLOCK_SIZE;
>       tcg_ctx.tb_ctx.tbs =
>               g_malloc(tcg_ctx.code_gen_max_blocks * sizeof(TranslationBlock));
> +    qemu_mutex_init(&tcg_ctx.tb_ctx.tb_lock);
Maybe we can initialize the mutex only for CONFIG_USER_ONLY?

Fred
>   }
>   
>   /* Must be called before using the QEMU cpus. 'tb_size' is the size

  reply	other threads:[~2015-08-13 12:17 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-12 16:40 [Qemu-devel] [PATCH 00/10] translate-all.c thread-safety Paolo Bonzini
2015-08-12 16:40 ` [Qemu-devel] [PATCH 01/10] cpus: protect work list with work_mutex Paolo Bonzini
2015-08-28 14:33   ` Peter Maydell
2015-08-12 16:40 ` [Qemu-devel] [PATCH 02/10] cpus: remove tcg_halt_cond global variable Paolo Bonzini
2015-08-13 13:05   ` Frederic Konrad
2015-08-13 13:08     ` Paolo Bonzini
2015-08-13 13:19       ` Frederic Konrad
2015-08-28 14:36   ` Peter Maydell
2015-08-29  6:52     ` Paolo Bonzini
2015-08-12 16:40 ` [Qemu-devel] [PATCH 03/10] replace spinlock by QemuMutex Paolo Bonzini
2015-08-13 12:17   ` Frederic Konrad [this message]
2015-08-13 13:12     ` Paolo Bonzini
2015-08-13 13:21       ` Frederic Konrad
2015-08-28 14:49   ` Peter Maydell
2015-08-28 14:53     ` Frederic Konrad
2015-08-29  6:51       ` Paolo Bonzini
2015-08-12 16:40 ` [Qemu-devel] [PATCH 04/10] exec-all: remove non-TCG stuff from exec-all.h header Paolo Bonzini
2015-08-28 14:53   ` Peter Maydell
2015-08-29  6:55     ` Paolo Bonzini
2015-08-12 16:40 ` [Qemu-devel] [PATCH 05/10] cpu-exec: elide more icount code if CONFIG_USER_ONLY Paolo Bonzini
2015-08-13 13:14   ` Frederic Konrad
2015-08-13 14:06     ` Paolo Bonzini
2015-08-28 14:56   ` Peter Maydell
2015-08-29  7:07     ` Paolo Bonzini
2015-08-12 16:40 ` [Qemu-devel] [PATCH 06/10] tcg: code_bitmap is not used by user-mode emulation Paolo Bonzini
2015-08-28 14:57   ` Peter Maydell
2015-08-29  7:13     ` Paolo Bonzini
2015-08-12 16:40 ` [Qemu-devel] [PATCH 07/10] tcg: comment on which functions have to be called with mmap_lock held Paolo Bonzini
2015-08-28 15:33   ` Peter Maydell
2015-08-29  6:57     ` Paolo Bonzini
2015-08-12 16:41 ` [Qemu-devel] [PATCH 08/10] tcg: add memory barriers in page_find_alloc accesses Paolo Bonzini
2015-08-12 20:37   ` Emilio G. Cota
2015-08-13  8:13     ` Paolo Bonzini
2015-08-13 19:50       ` Emilio G. Cota
2015-08-28 15:40   ` Peter Maydell
2015-08-29  6:58     ` Paolo Bonzini
2015-08-12 16:41 ` [Qemu-devel] [PATCH 09/10] exec: make mmap_lock/mmap_unlock globally available Paolo Bonzini
2015-08-28 15:42   ` Peter Maydell
2015-08-12 16:41 ` [Qemu-devel] [PATCH 10/10] cpu-exec: fix lock hierarchy for user-mode emulation Paolo Bonzini
2015-08-28 15:59   ` Peter Maydell
2015-08-12 16:41 ` [Qemu-devel] [PATCH 11/10] tcg: comment on which functions have to be called with tb_lock held Paolo Bonzini
2015-08-13 12:51   ` Frederic Konrad
2015-08-13 12:59     ` Paolo Bonzini
2015-08-13 13:32       ` Frederic Konrad
2015-08-13 14:39         ` Paolo Bonzini
2015-08-13 15:32           ` Peter Maydell
2015-08-13 16:20             ` Paolo Bonzini
2015-08-12 16:41 ` [Qemu-devel] [PATCH 12/10] tcg: protect TBContext with tb_lock Paolo Bonzini
2015-08-13 12:57   ` Frederic Konrad
2015-08-13 13:01     ` Paolo Bonzini
2015-08-13 13:04       ` Frederic Konrad
2015-08-14  9:26 ` [Qemu-devel] [PATCH 00/10] translate-all.c thread-safety Frederic Konrad

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=55CC8ADF.6040002@greensocs.com \
    --to=fred.konrad@greensocs.com \
    --cc=mttcg@greensocs.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.