Re: [Qemu-devel] [RFC v3 08/13] exec.c: introduce a simple rendezvous support

2015-07-17 Thread Alex Bennée

Alvise Rigo a.r...@virtualopensystems.com writes:

 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 jani.kokko...@huawei.com
 Suggested-by: Claudio Fontana claudio.font...@huawei.com
 Signed-off-by: Alvise Rigo a.r...@virtualopensystems.com
 ---
  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);
 +}
 +

I'll ignore this stuff for now as I assume we can all use the async work
patch of Fred's?


  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;
 +

I will however echo the hmmm on Fred's patch about the optimistic use
of volatile here. As Peter mentioned it is a red flag and I would prefer
explicit memory consistency behaviour used and documented.


  /* In order to avoid passing too many arguments to the MMIO helpers,
   * we store some rarely used information in the CPU context.
   */

-- 
Alex Bennée



Re: [Qemu-devel] [RFC v3 08/13] exec.c: introduce a simple rendezvous support

2015-07-17 Thread alvise rigo
On Fri, Jul 17, 2015 at 3:45 PM, Alex Bennée alex.ben...@linaro.org wrote:

 Alvise Rigo a.r...@virtualopensystems.com writes:

 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 jani.kokko...@huawei.com
 Suggested-by: Claudio Fontana claudio.font...@huawei.com
 Signed-off-by: Alvise Rigo a.r...@virtualopensystems.com
 ---
  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);
 +}
 +

 I'll ignore this stuff for now as I assume we can all use the async work
 patch of Fred's?

Yes, it will be more likely based on the plain async_run_on_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;
 +

 I will however echo the hmmm on Fred's patch about the optimistic use
 of volatile here. As Peter mentioned it is a red flag and I would prefer
 explicit memory consistency behaviour used and documented.

In my local branch I'm now using atomic_set/atomic_read, basically
what is defined in qemu/atomic.h. Is this enough?

Regards,
alvise



  /* In order to avoid passing too many arguments to the MMIO helpers,
   * we store some rarely used information in the CPU context.
   */

 --
 Alex Bennée



[Qemu-devel] [RFC v3 08/13] exec.c: introduce a simple rendezvous support

2015-07-10 Thread Alvise Rigo
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 jani.kokko...@huawei.com
Suggested-by: Claudio Fontana claudio.font...@huawei.com
Signed-off-by: Alvise Rigo a.r...@virtualopensystems.com
---
 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