All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: Peter Xu <peterx@redhat.com>
Cc: qemu-devel@nongnu.org, "Paolo Bonzini" <pbonzini@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Juraj Marcin" <jmarcin@redhat.com>,
	"Fabiano Rosas" <farosas@suse.de>,
	"Daniel P . Berrangé" <berrange@redhat.com>
Subject: Re: [PATCH RFC] bql: Fix bql_locked status with condvar APIs
Date: Thu, 21 Aug 2025 10:24:45 -0400	[thread overview]
Message-ID: <20250821142445.GB7010@fedora> (raw)
In-Reply-To: <20250820205051.24424-1-peterx@redhat.com>

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

On Wed, Aug 20, 2025 at 04:50:51PM -0400, Peter Xu wrote:
> QEMU has a per-thread "bql_locked" variable stored in TLS section, showing
> whether the current thread is holding the BQL lock.
> 
> It's a pretty handy variable.  Function-wise, QEMU have codes trying to
> conditionally take bql, relying on the var reflecting the locking status
> (e.g. BQL_LOCK_GUARD), or in a GDB debugging session, we could also look at
> the variable (in reality, co_tls_bql_locked), to see which thread is
> currently holding the bql.
> 
> When using that as a debugging facility, sometimes we can observe multiple
> threads holding bql at the same time. It's because QEMU's condvar APIs
> bypassed the bql_*() API, hence they do not update bql_locked even if they
> have released the mutex while waiting.
> 
> It can cause confusion if one does "thread apply all p co_tls_bql_locked"
> and see multiple threads reporting true.
> 
> Fix this by moving the bql status updates into the mutex debug hooks.  Now
> the variable should always reflect the reality.
> 
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>  include/qemu/main-loop.h  | 18 ++++++++++++++++++
>  util/qemu-thread-common.h |  7 +++++++
>  stubs/iothread-lock.c     |  9 +++++++++
>  system/cpus.c             | 14 ++++++++++++--
>  4 files changed, 46 insertions(+), 2 deletions(-)
> 
> diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
> index 4e2436b196..44fb430f5b 100644
> --- a/include/qemu/main-loop.h
> +++ b/include/qemu/main-loop.h
> @@ -270,6 +270,24 @@ void rust_bql_mock_lock(void);
>   */
>  bool bql_locked(void);
>  
> +/**
> + * mutex_is_bql:
> + *
> + * @mutex: the mutex pointer
> + *
> + * Returns whether the mutex is the BQL.
> + */
> +bool mutex_is_bql(QemuMutex *mutex);
> +
> +/**
> + * set_bql_locked:

This does not match the actual function name (bql_update_status()).

> + *
> + * @locked: update status on whether the BQL is locked
> + *
> + * NOTE: this should normally only be invoked when the status changed.
> + */
> +void bql_update_status(bool locked);
> +
>  /**
>   * bql_block: Allow/deny releasing the BQL
>   *
> diff --git a/util/qemu-thread-common.h b/util/qemu-thread-common.h
> index 2af6b12085..09331843ba 100644
> --- a/util/qemu-thread-common.h
> +++ b/util/qemu-thread-common.h
> @@ -14,6 +14,7 @@
>  #define QEMU_THREAD_COMMON_H
>  
>  #include "qemu/thread.h"
> +#include "qemu/main-loop.h"
>  #include "trace.h"
>  
>  static inline void qemu_mutex_post_init(QemuMutex *mutex)
> @@ -39,6 +40,9 @@ static inline void qemu_mutex_post_lock(QemuMutex *mutex,
>      mutex->line = line;
>  #endif
>      trace_qemu_mutex_locked(mutex, file, line);
> +    if (mutex_is_bql(mutex)) {
> +        bql_update_status(true);
> +    }
>  }
>  
>  static inline void qemu_mutex_pre_unlock(QemuMutex *mutex,
> @@ -49,6 +53,9 @@ static inline void qemu_mutex_pre_unlock(QemuMutex *mutex,
>      mutex->line = 0;
>  #endif
>      trace_qemu_mutex_unlock(mutex, file, line);
> +    if (mutex_is_bql(mutex)) {
> +        bql_update_status(false);
> +    }
>  }
>  
>  #endif
> diff --git a/stubs/iothread-lock.c b/stubs/iothread-lock.c
> index 6050c081f5..c89c9c7228 100644
> --- a/stubs/iothread-lock.c
> +++ b/stubs/iothread-lock.c
> @@ -34,3 +34,12 @@ void bql_block_unlock(bool increase)
>      assert((new_value > bql_unlock_blocked) == increase);
>      bql_unlock_blocked = new_value;
>  }
> +
> +bool mutex_is_bql(QemuMutex *mutex)
> +{
> +    return false;
> +}
> +
> +void bql_update_status(bool locked)
> +{
> +}
> diff --git a/system/cpus.c b/system/cpus.c
> index 256723558d..0bf677c4a2 100644
> --- a/system/cpus.c
> +++ b/system/cpus.c
> @@ -517,6 +517,18 @@ bool qemu_in_vcpu_thread(void)
>  
>  QEMU_DEFINE_STATIC_CO_TLS(bool, bql_locked)
>  
> +bool mutex_is_bql(QemuMutex *mutex)
> +{
> +    return mutex == &bql;
> +}
> +
> +void bql_update_status(bool locked)
> +{
> +    /* This function should only be used when an update happened.. */
> +    assert(bql_locked() != locked);
> +    set_bql_locked(locked);
> +}
> +
>  static uint32_t bql_unlock_blocked;
>  
>  void bql_block_unlock(bool increase)
> @@ -557,14 +569,12 @@ void bql_lock_impl(const char *file, int line)
>  
>      g_assert(!bql_locked());
>      bql_lock_fn(&bql, file, line);
> -    set_bql_locked(true);
>  }
>  
>  void bql_unlock(void)
>  {
>      g_assert(bql_locked());
>      g_assert(!bql_unlock_blocked);
> -    set_bql_locked(false);
>      qemu_mutex_unlock(&bql);
>  }
>  
> -- 
> 2.50.1
> 

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

  reply	other threads:[~2025-08-21 14:27 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-20 20:50 [PATCH RFC] bql: Fix bql_locked status with condvar APIs Peter Xu
2025-08-21 14:24 ` Stefan Hajnoczi [this message]
2025-08-21 16:24   ` Peter Xu

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=20250821142445.GB7010@fedora \
    --to=stefanha@redhat.com \
    --cc=berrange@redhat.com \
    --cc=farosas@suse.de \
    --cc=jmarcin@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=peterx@redhat.com \
    --cc=philmd@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 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.