qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Frederic Konrad <fred.konrad@greensocs.com>
To: "Alex Bennée" <alex.bennee@linaro.org>
Cc: mttcg@listserver.greensocs.com, peter.maydell@linaro.org,
	a.spyridakis@virtualopensystems.com, mark.burton@greensocs.com,
	agraf@suse.de, qemu-devel@nongnu.org,
	guillaume.delbergue@greensocs.com, pbonzini@redhat.com,
	alistair.francis@xilinx.com
Subject: Re: [Qemu-devel] [RFC PATCH V6 05/18] protect TBContext with tb_lock.
Date: Tue, 07 Jul 2015 15:16:43 +0200	[thread overview]
Message-ID: <559BD13B.4080804@greensocs.com> (raw)
In-Reply-To: <87pp449my7.fsf@linaro.org>

On 07/07/2015 14:22, Alex Bennée wrote:
> fred.konrad@greensocs.com writes:
>
>> From: KONRAD Frederic <fred.konrad@greensocs.com>
>>
>> This protects TBContext with tb_lock to make tb_* thread safe.
>>
>> We can still have issue with tb_flush in case of multithread TCG:
>>    An other CPU can be executing code during a flush.
>>
>> This can be fixed later by making all other TCG thread exiting before calling
>> tb_flush().
>>
>> tb_find_slow is separated into tb_find_slow and tb_find_physical as the whole
>> tb_find_slow doesn't require to lock the tb.
>>
>> Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
> So my comments from earlier about the different locking between
> CONFIG_USER and system emulation still stand. Ultimately we need a good
> reason (or an abstraction) before sprinkling #ifdefs in the code if only
> for ease of reading.

True.
>> Changes:
>> V1 -> V2:
>>    * Drop a tb_lock arround tb_find_fast in cpu-exec.c.
>> ---
>>   cpu-exec.c             |  60 ++++++++++++++--------
>>   target-arm/translate.c |   5 ++
>>   tcg/tcg.h              |   7 +++
>>   translate-all.c        | 137 ++++++++++++++++++++++++++++++++++++++-----------
>>   4 files changed, 158 insertions(+), 51 deletions(-)
>>
>> diff --git a/cpu-exec.c b/cpu-exec.c
>> index d6336d9..5d9b518 100644
>> --- a/cpu-exec.c
>> +++ b/cpu-exec.c
>> @@ -130,6 +130,8 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu)
>>   void cpu_loop_exit(CPUState *cpu)
>>   {
>>       cpu->current_tb = NULL;
>> +    /* Release those mutex before long jump so other thread can work. */
>> +    tb_lock_reset();
>>       siglongjmp(cpu->jmp_env, 1);
>>   }
>>   
>> @@ -142,6 +144,8 @@ void cpu_resume_from_signal(CPUState *cpu, void *puc)
>>       /* XXX: restore cpu registers saved in host registers */
>>   
>>       cpu->exception_index = -1;
>> +    /* Release those mutex before long jump so other thread can work. */
>> +    tb_lock_reset();
>>       siglongjmp(cpu->jmp_env, 1);
>>   }
>>   
>> @@ -253,12 +257,9 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
>>       tb_free(tb);
>>   }
>>   
>> -static TranslationBlock *tb_find_slow(CPUArchState *env,
>> -                                      target_ulong pc,
>> -                                      target_ulong cs_base,
>> -                                      uint64_t flags)
>> +static TranslationBlock *tb_find_physical(CPUArchState *env, target_ulong pc,
>> +                                          target_ulong cs_base, uint64_t flags)
>>   {
> As Paolo has already mentioned comments on functions expecting to have
> locks held when called.

Ok, will do that.
>> -    CPUState *cpu = ENV_GET_CPU(env);
>>       TranslationBlock *tb, **ptb1;
>>       unsigned int h;
>>       tb_page_addr_t phys_pc, phys_page1;
>> @@ -273,8 +274,9 @@ static TranslationBlock *tb_find_slow(CPUArchState *env,
>>       ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[h];
>>       for(;;) {
>>           tb = *ptb1;
>> -        if (!tb)
>> -            goto not_found;
>> +        if (!tb) {
>> +            return tb;
>> +        }
>>           if (tb->pc == pc &&
>>               tb->page_addr[0] == phys_page1 &&
>>               tb->cs_base == cs_base &&
>> @@ -282,28 +284,43 @@ static TranslationBlock *tb_find_slow(CPUArchState *env,
>>               /* check next page if needed */
>>               if (tb->page_addr[1] != -1) {
>>                   tb_page_addr_t phys_page2;
>> -
>>                   virt_page2 = (pc & TARGET_PAGE_MASK) +
>>                       TARGET_PAGE_SIZE;
>>                   phys_page2 = get_page_addr_code(env, virt_page2);
>> -                if (tb->page_addr[1] == phys_page2)
>> -                    goto found;
>> +                if (tb->page_addr[1] == phys_page2) {
>> +                    return tb;
>> +                }
>>               } else {
>> -                goto found;
>> +                return tb;
>>               }
>>           }
>>           ptb1 = &tb->phys_hash_next;
>>       }
>> - not_found:
>> -   /* if no translated code available, then translate it now */
>> -    tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
>> -
>> - found:
>> -    /* Move the last found TB to the head of the list */
>> -    if (likely(*ptb1)) {
>> -        *ptb1 = tb->phys_hash_next;
>> -        tb->phys_hash_next = tcg_ctx.tb_ctx.tb_phys_hash[h];
>> -        tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
>> +    return tb;
>> +}
>> +
>> +static TranslationBlock *tb_find_slow(CPUArchState *env, target_ulong pc,
>> +                                      target_ulong cs_base, uint64_t flags)
>> +{
>> +    /*
>> +     * First try to get the tb if we don't find it we need to lock and compile
>> +     * it.
>> +     */
>> +    CPUState *cpu = ENV_GET_CPU(env);
>> +    TranslationBlock *tb;
>> +
>> +    tb = tb_find_physical(env, pc, cs_base, flags);
>> +    if (!tb) {
>> +        tb_lock();
>> +        /*
>> +         * Retry to get the TB in case a CPU just translate it to avoid having
>> +         * duplicated TB in the pool.
>> +         */
>> +        tb = tb_find_physical(env, pc, cs_base, flags);
>> +        if (!tb) {
>> +            tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
>> +        }
>> +        tb_unlock();
>>       }
>>       /* we add the TB in the virtual pc hash table */
>>       cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
>> @@ -326,6 +343,7 @@ static inline TranslationBlock *tb_find_fast(CPUArchState *env)
>>                    tb->flags != flags)) {
>>           tb = tb_find_slow(env, pc, cs_base, flags);
>>       }
>> +
>>       return tb;
>>   }
>>   
>> diff --git a/target-arm/translate.c b/target-arm/translate.c
>> index 971b6db..47345aa 100644
>> --- a/target-arm/translate.c
>> +++ b/target-arm/translate.c
>> @@ -11162,6 +11162,8 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
>>   
>>       dc->tb = tb;
>>   
>> +    tb_lock();
>> +
>>       dc->is_jmp = DISAS_NEXT;
>>       dc->pc = pc_start;
>>       dc->singlestep_enabled = cs->singlestep_enabled;
>> @@ -11499,6 +11501,7 @@ done_generating:
>>           tb->size = dc->pc - pc_start;
>>           tb->icount = num_insns;
>>       }
>> +    tb_unlock();
>>   }
>>   
>>   void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
>> @@ -11567,6 +11570,7 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
>>   
>>   void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
>>   {
>> +    tb_lock();
>>       if (is_a64(env)) {
>>           env->pc = tcg_ctx.gen_opc_pc[pc_pos];
>>           env->condexec_bits = 0;
>> @@ -11574,4 +11578,5 @@ void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
>>           env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
>>           env->condexec_bits = gen_opc_condexec_bits[pc_pos];
>>       }
>> +    tb_unlock();
>>   }
>> diff --git a/tcg/tcg.h b/tcg/tcg.h
>> index 41e4869..032fe10 100644
>> --- a/tcg/tcg.h
>> +++ b/tcg/tcg.h
>> @@ -592,17 +592,24 @@ 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;
>>       uint8_t *ptr, *ptr_end;
>> +    tb_lock();
>>       size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
>>       ptr = s->pool_cur;
>>       ptr_end = ptr + size;
>>       if (unlikely(ptr_end > s->pool_end)) {
>> +        tb_unlock();
>>           return tcg_malloc_internal(&tcg_ctx, size);
> If the purpose of the lock is to protect the global tcg_ctx then we
> shouldn't be unlocking before calling the _internal function which also
> messes with the context.
>

Good point! I missed that.

>>       } else {
>>           s->pool_cur = ptr_end;
>> +        tb_unlock();
>>           return ptr;
>>       }
>>   }
>> diff --git a/translate-all.c b/translate-all.c
>> index b6b0e1c..c25b79b 100644
>> --- a/translate-all.c
>> +++ b/translate-all.c
>> @@ -127,6 +127,34 @@ static void *l1_map[V_L1_SIZE];
>>   /* code generation context */
>>   TCGContext tcg_ctx;
>>   
>> +/* translation block context */
>> +__thread volatile int have_tb_lock;
>> +
>> +void tb_lock(void)
>> +{
>> +    if (!have_tb_lock) {
>> +        qemu_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
>> +    }
>> +    have_tb_lock++;
>> +}
>> +
>> +void tb_unlock(void)
>> +{
>> +    assert(have_tb_lock > 0);
>> +    have_tb_lock--;
>> +    if (!have_tb_lock) {
>> +        qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
>> +    }
>> +}
>> +
>> +void tb_lock_reset(void)
>> +{
>> +    if (have_tb_lock) {
>> +        qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
>> +    }
>> +    have_tb_lock = 0;
>> +}
>> +
>>   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);
>> @@ -215,6 +243,7 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
>>   #ifdef CONFIG_PROFILER
>>       ti = profile_getclock();
>>   #endif
>> +    tb_lock();
>>       tcg_func_start(s);
>>   
>>       gen_intermediate_code_pc(env, tb);
>> @@ -228,8 +257,10 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
>>   
>>       /* find opc index corresponding to search_pc */
>>       tc_ptr = (uintptr_t)tb->tc_ptr;
>> -    if (searched_pc < tc_ptr)
>> +    if (searched_pc < tc_ptr) {
>> +        tb_unlock();
>>           return -1;
>> +    }
>>   
>>       s->tb_next_offset = tb->tb_next_offset;
>>   #ifdef USE_DIRECT_JUMP
>> @@ -241,8 +272,10 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
>>   #endif
>>       j = tcg_gen_code_search_pc(s, (tcg_insn_unit *)tc_ptr,
>>                                  searched_pc - tc_ptr);
>> -    if (j < 0)
>> +    if (j < 0) {
>> +        tb_unlock();
>>           return -1;
>> +    }
>>       /* now find start of instruction before */
>>       while (s->gen_opc_instr_start[j] == 0) {
>>           j--;
>> @@ -255,6 +288,8 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
>>       s->restore_time += profile_getclock() - ti;
>>       s->restore_count++;
>>   #endif
>> +
>> +    tb_unlock();
>>       return 0;
>>   }
>>   
>> @@ -672,6 +707,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);
>>   }
>>   
>>   /* Must be called before using the QEMU cpus. 'tb_size' is the size
>> @@ -696,16 +732,22 @@ bool tcg_enabled(void)
>>       return tcg_ctx.code_gen_buffer != NULL;
>>   }
>>   
>> -/* Allocate a new translation block. Flush the translation buffer if
>> -   too many translation blocks or too much generated code. */
>> +/*
>> + * Allocate a new translation block. Flush the translation buffer if
>> + * too many translation blocks or too much generated code.
>> + * tb_alloc is not thread safe but tb_gen_code is protected by a mutex so this
>> + * function is called only by one thread.
> maybe: "..is not thread safe but tb_gen_code is protected by tb_lock so
> only one thread calls it at a time."?

Yes.
>> + */
>>   static TranslationBlock *tb_alloc(target_ulong pc)
>>   {
>> -    TranslationBlock *tb;
>> +    TranslationBlock *tb = NULL;
>>   
>>       if (tcg_ctx.tb_ctx.nb_tbs >= tcg_ctx.code_gen_max_blocks ||
>>           (tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer) >=
>>            tcg_ctx.code_gen_buffer_max_size) {
>> -        return NULL;
>> +        tb = &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++];
>> +        tb->pc = pc;
>> +        tb->cflags = 0;
>>       }
>>       tb = &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++];
>>       tb->pc = pc;
> That looks weird.
>
> if (cond) return
> &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++] then return
> &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++];?
>
> Also rendering the setting of tb = NULL pointless as it will always be
> from the array?

Oops yes sorry, this is definitely a mistake, those changes should have
disappeared.

Thanks,
Fred
>
>> @@ -718,11 +760,16 @@ void tb_free(TranslationBlock *tb)
>>       /* In pr      actice this is mostly used for single use temporary TB
>>          Ignore the hard cases and just back up if this TB happens to
>>          be the last one generated.  */
>> +
>> +    tb_lock();
>> +
>>       if (tcg_ctx.tb_ctx.nb_tbs > 0 &&
>>               tb == &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs - 1]) {
>>           tcg_ctx.code_gen_ptr = tb->tc_ptr;
>>           tcg_ctx.tb_ctx.nb_tbs--;
>>       }
>> +
>> +    tb_unlock();
>>   }
>>   
>>   static inline void invalidate_page_bitmap(PageDesc *p)
>> @@ -773,6 +820,8 @@ void tb_flush(CPUArchState *env1)
>>   {
>>       CPUState *cpu = ENV_GET_CPU(env1);
>>   
>> +    tb_lock();
>> +
>>   #if defined(DEBUG_FLUSH)
>>       printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
>>              (unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer),
>> @@ -797,6 +846,8 @@ void tb_flush(CPUArchState *env1)
>>       /* XXX: flush processor icache at this point if cache flush is
>>          expensive */
>>       tcg_ctx.tb_ctx.tb_flush_count++;
>> +
>> +    tb_unlock();
>>   }
>>   
>>   #ifdef DEBUG_TB_CHECK
>> @@ -806,6 +857,8 @@ static void tb_invalidate_check(target_ulong address)
>>       TranslationBlock *tb;
>>       int i;
>>   
>> +    tb_lock();
>> +
>>       address &= TARGET_PAGE_MASK;
>>       for (i = 0; i < CODE_GEN_PHYS_HASH_SIZE; i++) {
>>           for (tb = tb_ctx.tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
>> @@ -817,6 +870,8 @@ static void tb_invalidate_check(target_ulong address)
>>               }
>>           }
>>       }
>> +
>> +    tb_unlock();
>>   }
>>   
>>   /* verify that all the pages have correct rights for code */
>> @@ -825,6 +880,8 @@ static void tb_page_check(void)
>>       TranslationBlock *tb;
>>       int i, flags1, flags2;
>>   
>> +    tb_lock();
>> +
>>       for (i = 0; i < CODE_GEN_PHYS_HASH_SIZE; i++) {
>>           for (tb = tcg_ctx.tb_ctx.tb_phys_hash[i]; tb != NULL;
>>                   tb = tb->phys_hash_next) {
>> @@ -836,6 +893,8 @@ static void tb_page_check(void)
>>               }
>>           }
>>       }
>> +
>> +    tb_unlock();
>>   }
>>   
>>   #endif
>> @@ -916,6 +975,8 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
>>       tb_page_addr_t phys_pc;
>>       TranslationBlock *tb1, *tb2;
>>   
>> +    tb_lock();
>> +
>>       /* remove the TB from the hash list */
>>       phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
>>       h = tb_phys_hash_func(phys_pc);
>> @@ -963,6 +1024,7 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
>>       tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2); /* fail safe */
>>   
>>       tcg_ctx.tb_ctx.tb_phys_invalidate_count++;
>> +    tb_unlock();
>>   }
>>   
>>   static void build_page_bitmap(PageDesc *p)
>> @@ -1004,6 +1066,8 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
>>       target_ulong virt_page2;
>>       int code_gen_size;
>>   
>> +    tb_lock();
>> +
>>       phys_pc = get_page_addr_code(env, pc);
>>       if (use_icount) {
>>           cflags |= CF_USE_ICOUNT;
>> @@ -1032,6 +1096,8 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
>>           phys_page2 = get_page_addr_code(env, virt_page2);
>>       }
>>       tb_link_page(tb, phys_pc, phys_page2);
>> +
>> +    tb_unlock();
>>       return tb;
>>   }
>>   
>> @@ -1330,13 +1396,15 @@ static inline void tb_alloc_page(TranslationBlock *tb,
>>   }
>>   
>>   /* add a new TB and link it to the physical page tables. phys_page2 is
>> -   (-1) to indicate that only one page contains the TB. */
>> + * (-1) to indicate that only one page contains the TB. */
>>   static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
>>                            tb_page_addr_t phys_page2)
>>   {
>>       unsigned int h;
>>       TranslationBlock **ptb;
>>   
>> +    tb_lock();
>> +
>>       /* Grab the mmap lock to stop another thread invalidating this TB
>>          before we are done.  */
>>       mmap_lock();
>> @@ -1370,6 +1438,8 @@ static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
>>       tb_page_check();
>>   #endif
>>       mmap_unlock();
>> +
>> +    tb_unlock();
>>   }
>>   
>>   /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
>> @@ -1378,31 +1448,34 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
>>   {
>>       int m_min, m_max, m;
>>       uintptr_t v;
>> -    TranslationBlock *tb;
>> -
>> -    if (tcg_ctx.tb_ctx.nb_tbs <= 0) {
>> -        return NULL;
>> -    }
>> -    if (tc_ptr < (uintptr_t)tcg_ctx.code_gen_buffer ||
>> -        tc_ptr >= (uintptr_t)tcg_ctx.code_gen_ptr) {
>> -        return NULL;
>> -    }
>> -    /* binary search (cf Knuth) */
>> -    m_min = 0;
>> -    m_max = tcg_ctx.tb_ctx.nb_tbs - 1;
>> -    while (m_min <= m_max) {
>> -        m = (m_min + m_max) >> 1;
>> -        tb = &tcg_ctx.tb_ctx.tbs[m];
>> -        v = (uintptr_t)tb->tc_ptr;
>> -        if (v == tc_ptr) {
>> -            return tb;
>> -        } else if (tc_ptr < v) {
>> -            m_max = m - 1;
>> -        } else {
>> -            m_min = m + 1;
>> +    TranslationBlock *tb = NULL;
>> +
>> +    tb_lock();
>> +
>> +    if ((tcg_ctx.tb_ctx.nb_tbs > 0)
>> +    && (tc_ptr >= (uintptr_t)tcg_ctx.code_gen_buffer &&
>> +        tc_ptr < (uintptr_t)tcg_ctx.code_gen_ptr)) {
>> +        /* binary search (cf Knuth) */
>> +        m_min = 0;
>> +        m_max = tcg_ctx.tb_ctx.nb_tbs - 1;
>> +        while (m_min <= m_max) {
>> +            m = (m_min + m_max) >> 1;
>> +            tb = &tcg_ctx.tb_ctx.tbs[m];
>> +            v = (uintptr_t)tb->tc_ptr;
>> +            if (v == tc_ptr) {
>> +                tb_unlock();
>> +                return tb;
>> +            } else if (tc_ptr < v) {
>> +                m_max = m - 1;
>> +            } else {
>> +                m_min = m + 1;
>> +            }
>>           }
>> +        tb = &tcg_ctx.tb_ctx.tbs[m_max];
>>       }
>> -    return &tcg_ctx.tb_ctx.tbs[m_max];
>> +
>> +    tb_unlock();
>> +    return tb;
>>   }
>>   
>>   #if !defined(CONFIG_USER_ONLY)
>> @@ -1564,6 +1637,8 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
>>       int direct_jmp_count, direct_jmp2_count, cross_page;
>>       TranslationBlock *tb;
>>   
>> +    tb_lock();
>> +
>>       target_code_size = 0;
>>       max_target_code_size = 0;
>>       cross_page = 0;
>> @@ -1619,6 +1694,8 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
>>               tcg_ctx.tb_ctx.tb_phys_invalidate_count);
>>       cpu_fprintf(f, "TLB flush count     %d\n", tlb_flush_count);
>>       tcg_dump_info(f, cpu_fprintf);
>> +
>> +    tb_unlock();
>>   }
>>   
>>   void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf)

  reply	other threads:[~2015-07-07 13:16 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-26 14:47 [Qemu-devel] [RFC PATCH V6 00/18] Multithread TCG fred.konrad
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 01/18] cpu: make cpu_thread_is_idle public fred.konrad
2015-07-07  9:47   ` Alex Bennée
2015-07-07 11:43     ` Frederic Konrad
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 02/18] replace spinlock by QemuMutex fred.konrad
2015-07-07 10:15   ` Alex Bennée
2015-07-07 10:22     ` Paolo Bonzini
2015-07-07 11:48       ` Frederic Konrad
2015-07-07 12:34         ` Paolo Bonzini
2015-07-07 13:06           ` Frederic Konrad
2015-07-07 11:46     ` Frederic Konrad
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 03/18] remove unused spinlock fred.konrad
2015-06-26 14:53   ` Paolo Bonzini
2015-06-26 15:29     ` Frederic Konrad
2015-06-26 15:46       ` Paolo Bonzini
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 04/18] add support for spin lock on POSIX systems exclusively fred.konrad
2015-06-26 14:55   ` Paolo Bonzini
2015-06-26 15:31     ` Frederic Konrad
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 05/18] protect TBContext with tb_lock fred.konrad
2015-06-26 14:56   ` Paolo Bonzini
2015-06-26 15:39     ` Frederic Konrad
2015-06-26 15:45       ` Paolo Bonzini
2015-06-26 16:20   ` Paolo Bonzini
2015-07-07 12:22   ` Alex Bennée
2015-07-07 13:16     ` Frederic Konrad [this message]
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 06/18] tcg: remove tcg_halt_cond global variable fred.konrad
2015-06-26 15:02   ` Paolo Bonzini
2015-06-26 15:41     ` Frederic Konrad
2015-07-07 12:27       ` Alex Bennée
2015-07-07 13:17         ` Frederic Konrad
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 07/18] Drop global lock during TCG code execution fred.konrad
2015-06-26 14:56   ` Jan Kiszka
2015-06-26 15:08     ` Paolo Bonzini
2015-06-26 15:36     ` Frederic Konrad
2015-06-26 15:42       ` Jan Kiszka
2015-06-26 16:11         ` Frederic Konrad
2015-07-07 12:33       ` Alex Bennée
2015-07-07 13:18         ` Frederic Konrad
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 08/18] cpu: remove exit_request global fred.konrad
2015-06-26 15:03   ` Paolo Bonzini
2015-07-07 13:04   ` Alex Bennée
2015-07-07 13:25     ` Frederic Konrad
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 09/18] cpu: add a tcg_executing flag fred.konrad
2015-07-07 13:23   ` Alex Bennée
2015-07-07 13:30     ` Frederic Konrad
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 10/18] tcg: switch on multithread fred.konrad
2015-07-07 13:40   ` Alex Bennée
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 11/18] cpus: make qemu_cpu_kick_thread public fred.konrad
2015-07-07 15:11   ` Alex Bennée
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 12/18] Use atomic cmpxchg to atomically check the exclusive value in a STREX fred.konrad
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 13/18] cpu: introduce async_run_safe_work_on_cpu fred.konrad
2015-06-26 15:35   ` Paolo Bonzini
2015-06-26 16:09     ` Frederic Konrad
2015-06-26 16:23       ` Paolo Bonzini
2015-06-26 16:36         ` Frederic Konrad
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 14/18] add a callback when tb_invalidate is called fred.konrad
2015-06-26 16:20   ` Paolo Bonzini
2015-06-26 16:40     ` Frederic Konrad
2015-07-07 15:32   ` Alex Bennée
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 15/18] cpu: introduce tlb_flush*_all fred.konrad
2015-06-26 15:15   ` Paolo Bonzini
2015-06-26 15:54     ` Frederic Konrad
2015-06-26 16:01       ` Paolo Bonzini
2015-06-26 16:08         ` Peter Maydell
2015-06-26 16:30           ` Frederic Konrad
2015-06-26 16:31             ` Paolo Bonzini
2015-06-26 16:35               ` Frederic Konrad
2015-06-26 16:39                 ` Paolo Bonzini
2015-07-06 14:29             ` Mark Burton
2015-07-07 16:12               ` Alex Bennée
2015-06-26 16:54           ` Paolo Bonzini
2015-07-08 15:35           ` Frederic Konrad
2015-07-07 15:52   ` Alex Bennée
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 16/18] arm: use tlb_flush*_all fred.konrad
2015-07-07 16:14   ` Alex Bennée
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 17/18] translate-all: introduces tb_flush_safe fred.konrad
2015-07-07 16:16   ` Alex Bennée
2015-06-26 14:47 ` [Qemu-devel] [RFC PATCH V6 18/18] translate-all: (wip) use tb_flush_safe when we can't alloc more tb fred.konrad
2015-06-26 16:21   ` Paolo Bonzini
2015-06-26 16:38     ` Frederic Konrad
2015-07-07 16:17   ` Alex Bennée
2015-07-07 16:23     ` 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=559BD13B.4080804@greensocs.com \
    --to=fred.konrad@greensocs.com \
    --cc=a.spyridakis@virtualopensystems.com \
    --cc=agraf@suse.de \
    --cc=alex.bennee@linaro.org \
    --cc=alistair.francis@xilinx.com \
    --cc=guillaume.delbergue@greensocs.com \
    --cc=mark.burton@greensocs.com \
    --cc=mttcg@listserver.greensocs.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).