All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@gmail.com>
To: Robert Foley <robert.foley@linaro.org>
Cc: peter.puhov@linaro.org, cota@braap.org, alex.bennee@linaro.org,
	qemu-devel@nongnu.org, Lingfeng Yang <lfy@google.com>
Subject: Re: [PATCH 01/19] configure: add --enable-tsan flag + fiber annotations for coroutine-ucontext
Date: Wed, 17 Jun 2020 15:24:07 +0100	[thread overview]
Message-ID: <20200617142407.GH1728005@stefanha-x1.localdomain> (raw)
In-Reply-To: <20200522160755.886-2-robert.foley@linaro.org>

[-- Attachment #1: Type: text/plain, Size: 4358 bytes --]

On Fri, May 22, 2020 at 12:07:37PM -0400, Robert Foley wrote:
> +#define UC_DEBUG 0
> +#if UC_DEBUG && defined(CONFIG_TSAN)
> +#define UC_TRACE(fmt, ...) fprintf(stderr, "%s:%d:%p " fmt "\n", \
> +    __func__, __LINE__, __tsan_get_current_fiber(), ##__VA_ARGS__);
> +#else
> +#define UC_TRACE(fmt, ...)
> +#endif

QEMU has tracing support, see docs/devel/tracing.txt. These fprintfs
should be trace events defined in the util/trace-events file.

> +
>  /**
>   * Per-thread coroutine bookkeeping
>   */
> @@ -65,7 +80,20 @@ union cc_arg {
>      int i[2];
>  };
>  
> -static void finish_switch_fiber(void *fake_stack_save)
> +/* QEMU_ALWAYS_INLINE only does so if __OPTIMIZE__, so we cannot use it. */
> +static inline __attribute__((always_inline))

Please document why always_inline is necessary here and in other
functions. Is it for performance or because the __tsan_*() functions
need to be called from a the parent function?

> +void on_new_fiber(CoroutineUContext *co)
> +{
> +#ifdef CONFIG_TSAN
> +    co->tsan_co_fiber = __tsan_create_fiber(0); /* flags: sync on switch */
> +    co->tsan_caller_fiber = __tsan_get_current_fiber();
> +    UC_TRACE("Create new TSAN co fiber. co: %p co fiber: %p caller fiber: %p ",
> +             co, co->tsan_co_fiber, co->tsan_caller_fiber);
> +#endif
> +}
> +
> +static inline __attribute__((always_inline))
> +void finish_switch_fiber(void *fake_stack_save)
>  {
>  #ifdef CONFIG_ASAN
>      const void *bottom_old;
> @@ -78,18 +106,40 @@ static void finish_switch_fiber(void *fake_stack_save)
>          leader.stack_size = size_old;
>      }
>  #endif
> +#ifdef CONFIG_TSAN
> +    if (fake_stack_save) {
> +        __tsan_release(fake_stack_save);
> +        __tsan_switch_to_fiber(fake_stack_save, 0);  /* 0=synchronize */
> +    }
> +#endif
>  }
>  
> -static void start_switch_fiber(void **fake_stack_save,
> -                               const void *bottom, size_t size)
> +static inline __attribute__((always_inline)) void start_switch_fiber(
> +    CoroutineAction action, void **fake_stack_save,
> +    const void *bottom, size_t size, void *new_fiber)
>  {
>  #ifdef CONFIG_ASAN
> -    __sanitizer_start_switch_fiber(fake_stack_save, bottom, size);
> +    if (action == COROUTINE_TERMINATE) {
> +        __sanitizer_start_switch_fiber(
> +            action == COROUTINE_TERMINATE ? NULL : fake_stack_save,

The if statement already checks action == COROUTINE_TERMINATE, why is it
being checked again?

I think the old behavior can be retained by dropping the if statement
like this:

  __sanitizer_start_switch_fiber(action == COROUTINE_TERMINATE ?
                                 NULL : fake_stack_save,
				 bottom, size);

> +            bottom, size);
> +    }
> +#endif
> +#ifdef CONFIG_TSAN
> +    void *curr_fiber =
> +        __tsan_get_current_fiber();
> +    __tsan_acquire(curr_fiber);
> +
> +    UC_TRACE("Current fiber: %p.", curr_fiber);
> +    *fake_stack_save = curr_fiber;
> +    UC_TRACE("Switch to fiber %p", new_fiber);
> +    __tsan_switch_to_fiber(new_fiber, 0);  /* 0=synchronize */
>  #endif
>  }

Please split start_switch_fiber() into two functions:
start_switch_fiber_asan() and start_switch_fiber_tsan(). That way the
asan- and tsan-specific arguments can be kept separate and the
co->tsan_* fields only need to be compiled in when CONFIG_TSAN is
defined.

For example:

  static inline __attribute__((always_inline))
  void start_switch_fiber_tsan(void **fake_stack_save,
                               CoroutineUContext *co,
  			     bool caller)
  {
  #ifdef CONFIG_TSAN
      void *new_fiber = caller ?
                        co->tsan_caller_fiber :
                        co->tsan_co_fiber;
      void *curr_fiber = __tsan_get_current_fiber();
      __tsan_acquire(curr_fiber);

      UC_TRACE("Current fiber: %p.", curr_fiber);
      *fake_stack_save = curr_fiber;
      UC_TRACE("Switch to fiber %p", new_fiber);
      __tsan_switch_to_fiber(new_fiber, 0);  /* 0=synchronize */
  #endif
  }

This does two things:
1. Unrelated ASAN and TSAN code is separate and each function only
   has arguments that are actually needed.
2. The co->tsan_caller_fiber and co->tsan_co_fiber fields are only
   access from within #ifdef CONFIG_TSAN.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

  parent reply	other threads:[~2020-06-17 14:26 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-22 16:07 [PATCH 00/19] Add Thread Sanitizer support to QEMU Robert Foley
2020-05-22 16:07 ` [PATCH 01/19] configure: add --enable-tsan flag + fiber annotations for coroutine-ucontext Robert Foley
2020-05-23 16:55   ` Philippe Mathieu-Daudé
2020-05-26 12:38     ` Robert Foley
2020-06-17 14:24   ` Stefan Hajnoczi [this message]
2020-06-17 15:56     ` Alex Bennée
2020-06-17 21:27     ` Robert Foley
2020-05-22 16:07 ` [PATCH 02/19] cpu: convert queued work to a QSIMPLEQ Robert Foley
2020-05-24 10:20   ` Philippe Mathieu-Daudé
2020-05-26 15:01     ` Robert Foley
2020-05-22 16:07 ` [PATCH 03/19] thread: add qemu_spin_destroy Robert Foley
2020-05-22 16:07 ` [PATCH 04/19] cputlb: destroy CPUTLB with tlb_destroy Robert Foley
2020-05-22 16:07 ` [PATCH 05/19] qht: call qemu_spin_destroy for head buckets Robert Foley
2020-05-22 16:07 ` [PATCH 06/19] tcg: call qemu_spin_destroy for tb->jmp_lock Robert Foley
2020-05-22 16:07 ` [PATCH 07/19] translate-all: call qemu_spin_destroy for PageDesc Robert Foley
2020-05-22 16:07 ` [PATCH 08/19] thread: add tsan annotations to QemuSpin Robert Foley
2020-05-22 16:07 ` [PATCH 09/19] tests/docker: Added docker build support for TSan Robert Foley
2020-05-22 16:07 ` [PATCH 10/19] include/qemu: Added tsan.h for annotations Robert Foley
2020-05-23 17:20   ` Emilio G. Cota
2020-05-23 21:37     ` Emilio G. Cota
2020-05-22 16:07 ` [PATCH 11/19] accel/tcg: Fixed tsan warnings related to parallel_cpus Robert Foley
2020-05-23 17:21   ` Emilio G. Cota
2020-05-22 16:07 ` [PATCH 12/19] configure: added tsan support for blacklist Robert Foley
2020-05-23 17:27   ` Emilio G. Cota
2020-05-26 14:07     ` Robert Foley
2020-05-22 16:07 ` [PATCH 13/19] accel/tcg: Fixed tsan warnings Robert Foley
2020-05-23 20:06   ` Emilio G. Cota
2020-05-26 15:14     ` Robert Foley
2020-05-26 18:47   ` Paolo Bonzini
2020-05-22 16:07 ` [PATCH 14/19] util/async: " Robert Foley
2020-05-23 20:12   ` Emilio G. Cota
2020-05-26 15:19     ` Robert Foley
2020-05-26 10:32   ` Stefan Hajnoczi
2020-05-26 15:21     ` Robert Foley
2020-05-22 16:07 ` [PATCH 15/19] qht: Fix " Robert Foley
2020-05-23 20:44   ` Emilio G. Cota
2020-05-22 16:07 ` [PATCH 16/19] util: fixed tsan warnings in thread_pool.c Robert Foley
2020-05-26 20:18   ` Paolo Bonzini
2020-05-22 16:07 ` [PATCH 17/19] util: Added tsan annotate for thread name Robert Foley
2020-05-23 20:29   ` Emilio G. Cota
2020-05-22 16:07 ` [PATCH 18/19] target/arm: Fix tsan warning in cpu.c Robert Foley
2020-05-22 17:44   ` Peter Maydell
2020-05-22 21:33     ` Robert Foley
2020-05-22 22:36       ` Peter Maydell
2020-05-23 17:18         ` Emilio G. Cota
2020-05-26 14:01           ` Robert Foley
2020-05-22 16:07 ` [PATCH 19/19] docs: Added details on TSan to testing.rst Robert Foley
2020-05-23 20:29   ` Emilio G. Cota
2020-05-22 21:07 ` [PATCH 00/19] Add Thread Sanitizer support to QEMU no-reply
2020-05-23 21:36 ` Emilio G. Cota
2020-05-26 15:18   ` Robert Foley

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=20200617142407.GH1728005@stefanha-x1.localdomain \
    --to=stefanha@gmail.com \
    --cc=alex.bennee@linaro.org \
    --cc=cota@braap.org \
    --cc=lfy@google.com \
    --cc=peter.puhov@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=robert.foley@linaro.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.