From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45493) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZDTZ6-0004rz-7Q for qemu-devel@nongnu.org; Fri, 10 Jul 2015 04:21:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZDTZ2-0001Qw-1j for qemu-devel@nongnu.org; Fri, 10 Jul 2015 04:21:48 -0400 Received: from mail-wg0-f46.google.com ([74.125.82.46]:36432) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZDTZ1-0001Qp-SF for qemu-devel@nongnu.org; Fri, 10 Jul 2015 04:21:43 -0400 Received: by wgxm20 with SMTP id m20so59618978wgx.3 for ; Fri, 10 Jul 2015 01:21:43 -0700 (PDT) From: Alvise Rigo Date: Fri, 10 Jul 2015 10:23:41 +0200 Message-Id: <1436516626-8322-9-git-send-email-a.rigo@virtualopensystems.com> In-Reply-To: <1436516626-8322-1-git-send-email-a.rigo@virtualopensystems.com> References: <1436516626-8322-1-git-send-email-a.rigo@virtualopensystems.com> Subject: [Qemu-devel] [RFC v3 08/13] exec.c: introduce a simple rendezvous support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, mttcg@listserver.greensocs.com Cc: alex.bennee@linaro.org, jani.kokkonen@huawei.com, tech@virtualopensystems.com, claudio.fontana@huawei.com, pbonzini@redhat.com When a vCPU is about to set a memory page as exclusive, it needs to wait that all the running vCPUs finish to execute the current TB and to be aware of the exact moment when that happens. For this, add a simple rendezvous mechanism that will be used in softmmu_llsc_template.h to implement the ldlink operation. Suggested-by: Jani Kokkonen Suggested-by: Claudio Fontana Signed-off-by: Alvise Rigo --- cpus.c | 5 +++++ exec.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ include/qom/cpu.h | 16 ++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/cpus.c b/cpus.c index aee445a..f4d938e 100644 --- a/cpus.c +++ b/cpus.c @@ -1423,6 +1423,11 @@ static int tcg_cpu_exec(CPUArchState *env) qemu_mutex_unlock_iothread(); ret = cpu_exec(env); cpu->tcg_executing = 0; + + if (unlikely(cpu->pending_rdv)) { + cpu_exit_do_rendezvous(cpu); + } + qemu_mutex_lock_iothread(); #ifdef CONFIG_PROFILER tcg_time += profile_getclock() - ti; diff --git a/exec.c b/exec.c index 964e922..51958ed 100644 --- a/exec.c +++ b/exec.c @@ -746,6 +746,51 @@ void cpu_breakpoint_remove_all(CPUState *cpu, int mask) } } +/* Rendezvous implementation. + * The corresponding definitions are in include/qom/cpu.h. */ +CpuExitRendezvous cpu_exit_rendezvous; +inline void cpu_exit_init_rendezvous(void) +{ + CpuExitRendezvous *rdv = &cpu_exit_rendezvous; + + rdv->attendees = 0; +} + +inline void cpu_exit_rendezvous_add_attendee(CPUState *cpu) +{ + CpuExitRendezvous *rdv = &cpu_exit_rendezvous; + + if (!cpu->pending_rdv) { + cpu->pending_rdv = 1; + atomic_inc(&rdv->attendees); + } +} + +void cpu_exit_do_rendezvous(CPUState *cpu) +{ + CpuExitRendezvous *rdv = &cpu_exit_rendezvous; + + atomic_dec(&rdv->attendees); + + cpu->pending_rdv = 0; +} + +void cpu_exit_rendezvous_wait_others(CPUState *cpu) +{ + CpuExitRendezvous *rdv = &cpu_exit_rendezvous; + + while (rdv->attendees) { + g_usleep(TCG_RDV_POLLING_PERIOD); + } +} + +void cpu_exit_rendezvous_release(void) +{ + CpuExitRendezvous *rdv = &cpu_exit_rendezvous; + + rdv->attendees = 0; +} + /* enable or disable single step mode. EXCP_DEBUG is returned by the CPU loop after each instruction */ void cpu_single_step(CPUState *cpu, int enabled) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 8f3fe56..8d121b3 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -201,6 +201,20 @@ typedef struct CPUWatchpoint { QTAILQ_ENTRY(CPUWatchpoint) entry; } CPUWatchpoint; +/* Rendezvous support */ +#define TCG_RDV_POLLING_PERIOD 10 +typedef struct CpuExitRendezvous { + volatile int attendees; + QemuMutex lock; +} CpuExitRendezvous; + +extern CpuExitRendezvous cpu_exit_rendezvous; +void cpu_exit_init_rendezvous(void); +void cpu_exit_rendezvous_add_attendee(CPUState *cpu); +void cpu_exit_do_rendezvous(CPUState *cpu); +void cpu_exit_rendezvous_wait_others(CPUState *cpu); +void cpu_exit_rendezvous_release(void); + struct KVMState; struct kvm_run; @@ -291,6 +305,8 @@ struct CPUState { void *opaque; + volatile int pending_rdv; + /* In order to avoid passing too many arguments to the MMIO helpers, * we store some rarely used information in the CPU context. */ -- 2.4.5