From: Paolo Bonzini <pbonzini@redhat.com>
To: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>,
Jan Kiszka <jan.kiszka@siemens.com>,
qemu-devel@nongnu.org, Alex Bligh <alex@alex.org.uk>,
MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Subject: Re: [Qemu-devel] [PATCH 2/4] timer: protect timers_state's clock with seqlock
Date: Mon, 5 Aug 2013 09:29:04 -0400 (EDT) [thread overview]
Message-ID: <771358257.9598648.1375709344876.JavaMail.root@redhat.com> (raw)
In-Reply-To: <1375688006-16780-3-git-send-email-pingfank@linux.vnet.ibm.com>
> In kvm mode, vm_clock may be read outside BQL.
Not just in KVM mode (we will be able to use dataplane with TCG sooner
or later), actually.
Otherwise looks good!
Paolo
> This will make
> timers_state --the foundation of vm_clock exposed to race condition.
> Using private lock to protect it.
>
> Note in tcg mode, vm_clock still read inside BQL, so icount is
> left without change. As for cpu_ticks in timers_state, it
> is still protected by BQL.
>
> Lock rule: private lock innermost, ie BQL->"this lock"
>
> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> ---
> cpus.c | 36 +++++++++++++++++++++++++++++-------
> 1 file changed, 29 insertions(+), 7 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index 85e743d..ab92db9 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -107,12 +107,17 @@ static int64_t qemu_icount;
> typedef struct TimersState {
> int64_t cpu_ticks_prev;
> int64_t cpu_ticks_offset;
> + /* QemuClock will be read out of BQL, so protect is with private lock.
> + * As for cpu_ticks, no requirement to read it outside BQL.
> + * Lock rule: innermost
> + */
> + QemuSeqLock clock_seqlock;
> int64_t cpu_clock_offset;
> int32_t cpu_ticks_enabled;
> int64_t dummy;
> } TimersState;
>
> -TimersState timers_state;
> +static TimersState timers_state;
>
> /* Return the virtual CPU time, based on the instruction counter. */
> int64_t cpu_get_icount(void)
> @@ -132,6 +137,7 @@ int64_t cpu_get_icount(void)
> }
>
> /* return the host CPU cycle counter and handle stop/restart */
> +/* cpu_ticks is safely if holding BQL */
> int64_t cpu_get_ticks(void)
> {
> if (use_icount) {
> @@ -156,33 +162,46 @@ int64_t cpu_get_ticks(void)
> int64_t cpu_get_clock(void)
> {
> int64_t ti;
> - if (!timers_state.cpu_ticks_enabled) {
> - return timers_state.cpu_clock_offset;
> - } else {
> - ti = get_clock();
> - return ti + timers_state.cpu_clock_offset;
> - }
> + unsigned start;
> +
> + do {
> + start = seqlock_read_begin(&timers_state.clock_seqlock);
> + if (!timers_state.cpu_ticks_enabled) {
> + ti = timers_state.cpu_clock_offset;
> + } else {
> + ti = get_clock();
> + ti += timers_state.cpu_clock_offset;
> + }
> + } while (seqlock_read_check(&timers_state.clock_seqlock, start);
> +
> + return ti;
> }
>
> /* enable cpu_get_ticks() */
> void cpu_enable_ticks(void)
> {
> + /* Here, the really thing protected by seqlock is cpu_clock. */
> + seqlock_write_lock(&timers_state.clock_seqlock);
> if (!timers_state.cpu_ticks_enabled) {
> timers_state.cpu_ticks_offset -= cpu_get_real_ticks();
> timers_state.cpu_clock_offset -= get_clock();
> timers_state.cpu_ticks_enabled = 1;
> }
> + seqlock_write_unlock(&timers_state.clock_seqlock);
> }
>
> /* disable cpu_get_ticks() : the clock is stopped. You must not call
> cpu_get_ticks() after that. */
> void cpu_disable_ticks(void)
> {
> + /* Here, the really thing protected by seqlock is cpu_clock. */
> + seqlock_write_lock(&timers_state.clock_seqlock);
> if (timers_state.cpu_ticks_enabled) {
> timers_state.cpu_ticks_offset = cpu_get_ticks();
> timers_state.cpu_clock_offset = cpu_get_clock();
> timers_state.cpu_ticks_enabled = 0;
> }
> + seqlock_write_unlock(&timers_state.clock_seqlock);
> }
>
> /* Correlation between real and virtual time is always going to be
> @@ -364,6 +383,9 @@ static const VMStateDescription vmstate_timers = {
>
> void configure_icount(const char *option)
> {
> + QemuMutex *mutex = g_malloc0(sizeof(QemuMutex));
> + qemu_mutex_init(mutex);
> + seqlock_init(&timers_state.clock_seqlock, mutex);
> vmstate_register(NULL, 0, &vmstate_timers, &timers_state);
> if (!option) {
> return;
> --
> 1.8.1.4
>
>
next prev parent reply other threads:[~2013-08-05 13:29 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-05 7:33 [Qemu-devel] [PATCH 0/4]: timers thread-safe stuff Liu Ping Fan
2013-08-05 7:33 ` [Qemu-devel] [PATCH 1/4] seqlock: introduce read-write seqlock Liu Ping Fan
2013-08-05 7:33 ` [Qemu-devel] [PATCH 2/4] timer: protect timers_state's clock with seqlock Liu Ping Fan
2013-08-05 13:29 ` Paolo Bonzini [this message]
2013-08-06 5:58 ` liu ping fan
2013-08-06 7:31 ` Paolo Bonzini
2013-08-06 9:30 ` Stefan Hajnoczi
2013-08-07 5:46 ` liu ping fan
2013-08-05 7:33 ` [Qemu-devel] [PATCH 3/4] qemu-thread: add QemuEvent Liu Ping Fan
2013-08-05 7:33 ` [Qemu-devel] [PATCH 4/4] timer: make qemu_clock_enable sync between disable and timer's cb Liu Ping Fan
2013-08-05 10:53 ` Paolo Bonzini
2013-08-05 10:00 ` [Qemu-devel] [PATCH 0/4]: timers thread-safe stuff Alex Bligh
2013-08-06 5:37 ` liu ping fan
2013-08-06 6:14 ` Alex Bligh
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=771358257.9598648.1375709344876.JavaMail.root@redhat.com \
--to=pbonzini@redhat.com \
--cc=alex@alex.org.uk \
--cc=jan.kiszka@siemens.com \
--cc=kwolf@redhat.com \
--cc=morita.kazutaka@lab.ntt.co.jp \
--cc=pingfank@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/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.