diff mbox

[5/8] tcg: Clarify "thread safaty" check in tb_add_jump()

Message ID 1458815961-31979-6-git-send-email-sergey.fedorov@linaro.org
State New
Headers show

Commit Message

sergey.fedorov@linaro.org March 24, 2016, 10:39 a.m. UTC
From: Sergey Fedorov <serge.fdrv@gmail.com>

The check does not give an absolute guarantee of thread safety because
there still may be a race condition between two threads which both have
just read zero from jmp_list_next[n] and proceed with list modification.
Clarify this in the comment to attract here some attention.

Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
---
 include/exec/exec-all.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Paolo Bonzini March 24, 2016, 11:31 a.m. UTC | #1
On 24/03/2016 11:39, sergey.fedorov@linaro.org wrote:
> +    /* FIXME: This test provides only some probablistic "thread safety" for
> +     * user-mode emulation; appropriate synchronization/locking scheme should
> +     * be implemented.
> +     */

There is appropriate locking.  This code:

       if (next_tb != 0 && tb->page_addr[1] == -1
           && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
           tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
                       next_tb & TB_EXIT_MASK, tb);
       }

in cpu-exec.c runs under tb_lock.  However, two threads can decide to
call tb_add_jump at the same time outside the lock, so we have to check
inside the lock whether someone has already done the work.

What the comment means is that, in single-threaded scenarios (current
TCG and single-threaded user emulation), tb->jmp_list_next[n] is only
set once.

Paolo
Artyom Tarasenko March 24, 2016, 12:23 p.m. UTC | #2
s/safaty/safety/ ?

On Thu, Mar 24, 2016 at 11:39 AM,  <sergey.fedorov@linaro.org> wrote:
> From: Sergey Fedorov <serge.fdrv@gmail.com>
>
> The check does not give an absolute guarantee of thread safety because
> there still may be a race condition between two threads which both have
> just read zero from jmp_list_next[n] and proceed with list modification.
> Clarify this in the comment to attract here some attention.
>
> Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
> Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
> ---
>  include/exec/exec-all.h | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> index cd96219a89e7..4f36d109ac7f 100644
> --- a/include/exec/exec-all.h
> +++ b/include/exec/exec-all.h
> @@ -390,7 +390,10 @@ static inline void tb_set_jmp_target(TranslationBlock *tb,
>  static inline void tb_add_jump(TranslationBlock *tb, int n,
>                                 TranslationBlock *tb_next)
>  {
> -    /* NOTE: this test is only needed for thread safety */
> +    /* FIXME: This test provides only some probablistic "thread safety" for
> +     * user-mode emulation; appropriate synchronization/locking scheme should
> +     * be implemented.
> +     */
>      if (!tb->jmp_list_next[n]) {
>          /* patch the native jump address */
>          tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr);
> --
> 2.7.3
>
>
sergey.fedorov@linaro.org March 24, 2016, 12:28 p.m. UTC | #3
On 24/03/16 15:23, Artyom Tarasenko wrote:
> s/safaty/safety/ ?

Oops, silly typo :)

Thanks,
Sergey
Sergey Fedorov March 24, 2016, 12:41 p.m. UTC | #4
On 24/03/16 14:31, Paolo Bonzini wrote:
> On 24/03/2016 11:39, sergey.fedorov@linaro.org wrote:
>> +    /* FIXME: This test provides only some probablistic "thread safety" for
>> +     * user-mode emulation; appropriate synchronization/locking scheme should
>> +     * be implemented.
>> +     */
> There is appropriate locking.  This code:
>
>        if (next_tb != 0 && tb->page_addr[1] == -1
>            && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
>            tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
>                        next_tb & TB_EXIT_MASK, tb);
>        }
>
> in cpu-exec.c runs under tb_lock.  However, two threads can decide to
> call tb_add_jump at the same time outside the lock, so we have to check
> inside the lock whether someone has already done the work.
>
> What the comment means is that, in single-threaded scenarios (current
> TCG and single-threaded user emulation), tb->jmp_list_next[n] is only
> set once.

Right, thanks for clarifying this. So I'm going to put mention this in
the comment, then.

Kind regards,
Sergey
diff mbox

Patch

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index cd96219a89e7..4f36d109ac7f 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -390,7 +390,10 @@  static inline void tb_set_jmp_target(TranslationBlock *tb,
 static inline void tb_add_jump(TranslationBlock *tb, int n,
                                TranslationBlock *tb_next)
 {
-    /* NOTE: this test is only needed for thread safety */
+    /* FIXME: This test provides only some probablistic "thread safety" for
+     * user-mode emulation; appropriate synchronization/locking scheme should
+     * be implemented.
+     */
     if (!tb->jmp_list_next[n]) {
         /* patch the native jump address */
         tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr);