qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states
@ 2015-10-13 17:10 Lluís Vilanova
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv11/8] trace: Add support for vCPU pointers in trace events Lluís Vilanova
                   ` (8 more replies)
  0 siblings, 9 replies; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 17:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stefan Hajnoczi

Adds the "vcpu" event property to identify events tied to a specific vCPU. In
addition, it allows controlling the tracing state of such events on a per-vCPU
basis.

Events with the "vcpu" property are identified as being tied to a particular
virtual CPU, like executing an instruction. The state of such events can be
controlled idependently; this is specially useful to, for example, trace memory
access events of a process executing on a specific virtual CPU.

This event plays in combination with the "tcg" property to avoid generating a
call to the execution-time event tracer when a vCPU is not actively tracing such
event.

Virtual CPUs tracing the same set of events use the same physical translation
cache, improving their reuse. The system has 2^N physical translation caches,
where "N" is the number of TCG events with the "vcpu" property. Every vCPU has a
bitmap with the states of these events, which can be controlled separately, and
uses it to index into its physical translation cache. At translation time, QEMU
generates the code to trace an event at execution time only if the event is
enabled.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---

Lluís Vilanova (8):
      trace: Add support for vCPU pointers in trace events
      trace: Add 'vcpu' event property
      trace: [tcg] Identify events with the 'vcpu' property
      exec: [tcg] Refactor flush of per-CPU virtual TB cache
      exec: [ŧcg] Use multiple physical TB caches
      exec: [tcg] Track which vCPU is performing translation and execution
      [trivial] Track when QEMU has finished initialization
      trace: [tcg] Add per-vCPU tracing states for events with the 'vcpu' property


 Makefile.objs                            |    3 -
 bsd-user/main.c                          |    1 
 cpu-exec.c                               |   17 +++
 cputlb.c                                 |    2 
 docs/tracing.txt                         |   30 ++++++
 include/exec/exec-all.h                  |   16 +++
 include/qemu-common.h                    |    3 +
 include/qom/cpu.h                        |   10 ++
 linux-user/main.c                        |    1 
 qapi/trace.json                          |   36 +++++++
 qemu-common.c                            |   14 +++
 qmp-commands.hx                          |   27 +++++
 qom/cpu.c                                |   21 ++++
 scripts/tracetool/__init__.py            |   24 ++++-
 scripts/tracetool/format/events_c.py     |   11 ++
 scripts/tracetool/format/events_h.py     |   12 ++
 scripts/tracetool/format/h.py            |    4 +
 scripts/tracetool/format/tcg_h.py        |   19 +++-
 scripts/tracetool/format/tcg_helper_c.py |   11 ++
 scripts/tracetool/format/ust_events_c.py |    4 +
 scripts/tracetool/transform.py           |    9 ++
 stubs/Makefile.objs                      |    1 
 stubs/qemu-common-stub.c                 |   21 ++++
 target-alpha/translate.c                 |    3 -
 target-arm/translate.c                   |    3 -
 target-arm/translate.h                   |    2 
 target-cris/translate.c                  |    3 -
 target-cris/translate_v10.c              |    1 
 target-i386/translate.c                  |    3 -
 target-lm32/translate.c                  |    3 -
 target-m68k/translate.c                  |    3 -
 target-microblaze/translate.c            |    3 -
 target-mips/translate.c                  |    3 -
 target-moxie/translate.c                 |    3 -
 target-openrisc/translate.c              |    3 -
 target-ppc/translate.c                   |    3 -
 target-s390x/translate.c                 |    3 -
 target-sh4/translate.c                   |    3 -
 target-sparc/translate.c                 |    6 +
 target-tilegx/translate.c                |    3 -
 target-tricore/translate.c               |    3 -
 target-unicore32/translate.c             |    3 -
 target-xtensa/translate.c                |    3 -
 tcg/tcg-op.h                             |    2 
 tcg/tcg.h                                |   10 ++
 trace/Makefile.objs                      |    2 
 trace/control-internal.h                 |   25 ++++-
 trace/control-stub.c                     |   29 ++++++
 trace/control-target.c                   |   53 ++++++++++
 trace/control.h                          |   63 ++++++++++++
 trace/event-internal.h                   |    4 +
 trace/qmp.c                              |  129 +++++++++++++++++++++++--
 translate-all.c                          |  156 ++++++++++++++++++++++++++----
 translate-all.h                          |   49 +++++++++
 ui/Makefile.objs                         |    2 
 vl.c                                     |    2 
 56 files changed, 801 insertions(+), 82 deletions(-)
 create mode 100644 qemu-common.c
 create mode 100644 stubs/qemu-common-stub.c
 create mode 100644 trace/control-stub.c
 create mode 100644 trace/control-target.c


To: qemu-devel@nongnu.org
Cc: Stefan Hajnoczi <stefanha@gmail.com>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCHv11/8] trace: Add support for vCPU pointers in trace events
  2015-10-13 17:10 [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
@ 2015-10-13 17:10 ` Lluís Vilanova
  2015-10-16  9:13   ` Stefan Hajnoczi
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv12/8] trace: Add 'vcpu' event property Lluís Vilanova
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 17:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Guan Xuetao, Eduardo Habkost, Stefan Hajnoczi,
	Anthony Green, Mark Cave-Ayland, Jia Liu, Alexander Graf,
	Blue Swirl, Max Filippov, Michael Walle, open list:PowerPC,
	Stefan Hajnoczi, Edgar E. Iglesias, Paolo Bonzini,
	Bastian Koppelmann, Leon Alrae, Aurelien Jarno, Richard Henderson

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 scripts/tracetool/transform.py |    9 ++++++++-
 target-alpha/translate.c       |    2 +-
 target-arm/translate.c         |    2 +-
 target-arm/translate.h         |    2 +-
 target-cris/translate.c        |    2 +-
 target-i386/translate.c        |    2 +-
 target-lm32/translate.c        |    2 +-
 target-m68k/translate.c        |    2 +-
 target-microblaze/translate.c  |    2 +-
 target-mips/translate.c        |    2 +-
 target-moxie/translate.c       |    2 +-
 target-openrisc/translate.c    |    2 +-
 target-ppc/translate.c         |    2 +-
 target-s390x/translate.c       |    2 +-
 target-sh4/translate.c         |    2 +-
 target-sparc/translate.c       |    5 +++--
 target-tilegx/translate.c      |    2 +-
 target-tricore/translate.c     |    2 +-
 target-unicore32/translate.c   |    2 +-
 target-xtensa/translate.c      |    2 +-
 tcg/tcg-op.h                   |    2 --
 tcg/tcg.h                      |    6 ++++++
 trace/control.h                |    5 ++++-
 23 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/scripts/tracetool/transform.py b/scripts/tracetool/transform.py
index fc5e679..db3ed54 100644
--- a/scripts/tracetool/transform.py
+++ b/scripts/tracetool/transform.py
@@ -6,7 +6,7 @@ Type-transformation rules.
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2015, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -74,6 +74,7 @@ TCG_2_HOST = {
     "TCGv_i32": "uint32_t",
     "TCGv_i64": "uint64_t",
     "TCGv_ptr": "void *",
+    "TCGv_cpu": "CPUState *",
     None: _tcg_2_host,
     }
 
@@ -98,6 +99,7 @@ HOST_2_TCG = {
     "uint32_t": "TCGv_i32",
     "uint64_t": "TCGv_i64",
     "void *"  : "TCGv_ptr",
+    "CPUState *": "TCGv_cpu",
     None: _host_2_tcg,
     }
 
@@ -115,6 +117,8 @@ TCG_2_TCG_HELPER_DEF = {
     "TCGv_i32": "uint32_t",
     "TCGv_i64": "uint64_t",
     "TCGv_ptr": "void *",
+    "TCGv_cpu": "void *",
+    "CPUState *": "void *",
     None: _tcg_2_helper_def,
     }
 
@@ -130,6 +134,7 @@ TCG_2_TCG_HELPER_DECL = {
     "TCGv_ptr": "ptr",
     "TCGv_i32": "i32",
     "TCGv_i64": "i64",
+    "TCGv_cpu": "ptr",
     None: _tcg_2_tcg_helper_decl_error,
     }
 
@@ -146,6 +151,7 @@ HOST_2_TCG_TMP_NEW = {
     "uint32_t": "tcg_const_i32",
     "uint64_t": "tcg_const_i64",
     "void *"  : "tcg_const_ptr",
+    "CPUState *": "tcg_const_ptr",
     None: _host_2_tcg_tmp_new,
     }
 
@@ -162,5 +168,6 @@ HOST_2_TCG_TMP_FREE = {
     "uint32_t": "tcg_temp_free_i32",
     "uint64_t": "tcg_temp_free_i64",
     "void *"  : "tcg_temp_free_ptr",
+    "CPUState *": "tcg_temp_free_ptr",
     None: _host_2_tcg_tmp_free,
     }
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index f936d1b..6154519 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -91,7 +91,7 @@ typedef enum {
 } ExitStatus;
 
 /* global register indexes */
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv cpu_std_ir[31];
 static TCGv cpu_fir[31];
 static TCGv cpu_pc;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 22c3587..7dc7862 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -59,7 +59,7 @@
 #define IS_USER(s) (s->user)
 #endif
 
-TCGv_ptr cpu_env;
+TCGv_cpu cpu_env;
 /* We reuse the same 64-bit temporaries for efficiency.  */
 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
 static TCGv_i32 cpu_R[16];
diff --git a/target-arm/translate.h b/target-arm/translate.h
index 53ef971..6e8eb7d 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -70,7 +70,7 @@ typedef struct DisasCompare {
 } DisasCompare;
 
 /* Share the TCG temporaries common between 32 and 64 bit modes.  */
-extern TCGv_ptr cpu_env;
+extern TCGv_cpu cpu_env;
 extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
 extern TCGv_i64 cpu_exclusive_addr;
 extern TCGv_i64 cpu_exclusive_val;
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 964845c..9dd5c5f 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -58,7 +58,7 @@
 #define CC_MASK_NZVC 0xf
 #define CC_MASK_RNZV 0x10e
 
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv cpu_R[16];
 static TCGv cpu_PR[16];
 static TCGv cc_x;
diff --git a/target-i386/translate.c b/target-i386/translate.c
index ef10e68..e191224 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -62,7 +62,7 @@
 //#define MACRO_TEST   1
 
 /* global register indexes */
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv cpu_A0;
 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT;
 static TCGv_i32 cpu_cc_op;
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index c61ad0f..45abe53 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -42,7 +42,7 @@
 
 #define MEM_INDEX 0
 
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv cpu_R[32];
 static TCGv cpu_pc;
 static TCGv cpu_ie;
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 5995cce..e3ee9e0 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -48,7 +48,7 @@
 static TCGv_i32 cpu_halted;
 static TCGv_i32 cpu_exception_index;
 
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 
 static char cpu_reg_names[3*8*3 + 5*4];
 static TCGv cpu_dregs[8];
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index a9c5010..6b0915e 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -44,7 +44,7 @@
             (((src) >> start) & ((1 << (end - start + 1)) - 1))
 
 static TCGv env_debug;
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv cpu_R[32];
 static TCGv cpu_SR[18];
 static TCGv env_imm;
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 897839c..9ffb100 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1350,7 +1350,7 @@ enum {
 };
 
 /* global register indices */
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv cpu_gpr[32], cpu_PC;
 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
 static TCGv cpu_dspctrl, btarget, bcond;
diff --git a/target-moxie/translate.c b/target-moxie/translate.c
index f84841e..f8c70cb 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -59,7 +59,7 @@ enum {
 
 static TCGv cpu_pc;
 static TCGv cpu_gregs[16];
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv cc_a, cc_b;
 
 #include "exec/gen-icount.h"
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index b66fde1..c122c20 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -52,7 +52,7 @@ typedef struct DisasContext {
     uint32_t delayed_branch;
 } DisasContext;
 
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv cpu_sr;
 static TCGv cpu_R[32];
 static TCGv cpu_pc;
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index c2bc1a7..ff40c6b 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -47,7 +47,7 @@
 /* Code translation helpers                                                  */
 
 /* global register indexes */
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static char cpu_reg_names[10*3 + 22*4 /* GPR */
     + 10*4 + 22*5 /* SPE GPRh */
     + 10*4 + 22*5 /* FPR */
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 05d51fe..7e549d8 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -36,7 +36,7 @@
 #include "exec/cpu_ldst.h"
 
 /* global register indexes */
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 
 #include "exec/gen-icount.h"
 #include "exec/helper-proto.h"
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index f764bc2..7fb4900 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -59,7 +59,7 @@ enum {
 };
 
 /* global register indexes */
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv cpu_gregs[24];
 static TCGv cpu_sr, cpu_sr_m, cpu_sr_q, cpu_sr_t;
 static TCGv cpu_pc, cpu_ssr, cpu_spc, cpu_gbr;
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index b59742a..3d5d150 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -42,7 +42,8 @@
                          according to jump_pc[T2] */
 
 /* global register indexes */
-static TCGv_ptr cpu_env, cpu_regwptr;
+static TCGv_cpu cpu_env;
+static TCGv_ptr cpu_regwptr;
 static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
 static TCGv_i32 cpu_cc_op;
 static TCGv_i32 cpu_psr;
@@ -2294,7 +2295,7 @@ static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
 }
 
 #ifndef CONFIG_USER_ONLY
-static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_ptr cpu_env)
+static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_cpu cpu_env)
 {
     TCGv_i32 r_tl = tcg_temp_new_i32();
 
diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 34d45f8..0cd6700 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -30,7 +30,7 @@
 
 #define FMT64X                          "%016" PRIx64
 
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv cpu_pc;
 static TCGv cpu_regs[TILEGX_R_COUNT];
 
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 135c583..655db75 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -45,7 +45,7 @@ static TCGv cpu_PSW_SV;
 static TCGv cpu_PSW_AV;
 static TCGv cpu_PSW_SAV;
 /* CPU env */
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 
 #include "exec/gen-icount.h"
 
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 48f89fb..6ba52c2 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -51,7 +51,7 @@ typedef struct DisasContext {
    conditional executions state has been updated.  */
 #define DISAS_SYSCALL 5
 
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv_i32 cpu_R[32];
 
 /* FIXME:  These should be removed.  */
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index fda91b7..c6d7658 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -73,7 +73,7 @@ typedef struct DisasContext {
     unsigned cpenable;
 } DisasContext;
 
-static TCGv_ptr cpu_env;
+static TCGv_cpu cpu_env;
 static TCGv_i32 cpu_pc;
 static TCGv_i32 cpu_R[16];
 static TCGv_i32 cpu_FR[16];
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 4e20dc1..c446d3d 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -756,7 +756,6 @@ static inline void tcg_gen_exit_tb(uintptr_t val)
 void tcg_gen_goto_tb(unsigned idx);
 
 #if TARGET_LONG_BITS == 32
-#define TCGv TCGv_i32
 #define tcg_temp_new() tcg_temp_new_i32()
 #define tcg_global_reg_new tcg_global_reg_new_i32
 #define tcg_global_mem_new tcg_global_mem_new_i32
@@ -768,7 +767,6 @@ void tcg_gen_goto_tb(unsigned idx);
 #define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i32
 #define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32
 #else
-#define TCGv TCGv_i64
 #define tcg_temp_new() tcg_temp_new_i64()
 #define tcg_global_reg_new tcg_global_reg_new_i64
 #define tcg_global_mem_new tcg_global_mem_new_i64
diff --git a/tcg/tcg.h b/tcg/tcg.h
index a696922..1585551 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -308,6 +308,12 @@ typedef tcg_target_ulong TCGArg;
 typedef struct TCGv_i32_d *TCGv_i32;
 typedef struct TCGv_i64_d *TCGv_i64;
 typedef struct TCGv_ptr_d *TCGv_ptr;
+typedef TCGv_ptr TCGv_cpu;
+#if TARGET_LONG_BITS == 32
+typedef TCGv_i32 TCGv;
+#else  /* TARGET_LONG_BITS == 64 */
+typedef TCGv_i64 TCGv;
+#endif
 
 static inline TCGv_i32 QEMU_ARTIFICIAL MAKE_TCGV_I32(intptr_t i)
 {
diff --git a/trace/control.h b/trace/control.h
index da9bb6b..1a78a7b 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -1,7 +1,7 @@
 /*
  * Interface for configuring and controlling the state of tracing events.
  *
- * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2011-2015 Lluís Vilanova <vilanova@ac.upc.edu>
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -14,6 +14,9 @@
 #include "trace/generated-events.h"
 
 
+typedef struct CPUState CPUState;
+
+
 /**
  * TraceEventID:
  *

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCHv12/8] trace: Add 'vcpu' event property
  2015-10-13 17:10 [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv11/8] trace: Add support for vCPU pointers in trace events Lluís Vilanova
@ 2015-10-13 17:10 ` Lluís Vilanova
  2015-10-16  9:16   ` Stefan Hajnoczi
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv13/8] trace: [tcg] Identify events with the 'vcpu' property Lluís Vilanova
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 17:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stefan Hajnoczi, Stefan Hajnoczi

This property identifies events that trace vCPU-specific information.

It adds an implicit "CPUState*" argument that identifies the vCPU raising this
event. TCG translation events have an additional "TCGv_cpu" implicit argument
that is later used as the "CPUState*" argument at execution time.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 docs/tracing.txt                         |   30 ++++++++++++++++++++++++++++++
 scripts/tracetool/__init__.py            |   24 ++++++++++++++++++++++--
 scripts/tracetool/format/h.py            |    4 +++-
 scripts/tracetool/format/tcg_h.py        |   13 ++++++++++---
 scripts/tracetool/format/ust_events_c.py |    4 +++-
 5 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/docs/tracing.txt b/docs/tracing.txt
index 7117c5e..f0dba3d 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -347,3 +347,33 @@ This will immediately call:
 and will generate the TCG code to call:
 
     void trace_foo(uint8_t a1, uint32_t a2);
+
+=== "vcpu" ===
+
+Identifies events that trace vCPU-specific information. The property adds a
+"CPUState*" argument that identifies the vCPU raising the event. If used
+together with the "tcg" property, it adds a second "TCGv_cpu" argument that
+identifies the vCPU when guest code is executed.
+
+The following example events:
+
+    foo(uint32_t a) "a=%x"
+    vcpu bar(uint32_t a) "cpu=%p a=%x"
+    tcg vcpu baz(uint32_t a) "cpu=%p a=%x", "cpu=%p a=%x"
+
+Can be used as:
+
+    #include "trace-tcg.h"
+    
+    CPUArchState *env;
+    TCGv_ptr cpu_env;
+    
+    void some_disassembly_func(...)
+    {
+        /* trace emitted at this point */
+        trace_foo(0xcafe);
+        /* trace emitted at this point */
+        trace_bar(ENV_GET_CPU(env), 0xcafe);
+        /* trace emitted at this point (env) and when guest code is executed (cpu_env) */
+        trace_baz_tcg(ENV_GET_CPU(env), cpu_env, 0xcafe);
+    }
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 181675f..b75c66d 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -6,7 +6,7 @@ Machinery for generating tracing-related intermediate files.
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2015, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -146,7 +146,7 @@ class Event(object):
                       "(?:(?:(?P<fmt_trans>\".+),)?\s*(?P<fmt>\".+))?"
                       "\s*")
 
-    _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec"])
+    _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu"])
 
     def __init__(self, name, props, fmt, args, orig=None):
         """
@@ -215,6 +215,19 @@ class Event(object):
         if "tcg" in props and isinstance(fmt, str):
             raise ValueError("Events with 'tcg' property must have two formats")
 
+        # add implicit arguments when using the 'vcpu' property
+        if "vcpu" in props:
+            assert "tcg-trans" not in props and "tcg-exec" not in props
+            # events with 'tcg-trans' and 'tcg-exec' are auto-generated, they
+            # have already been transformed
+            if "tcg" in props:
+                types = ["TCGv_cpu"] + args.types()
+                names = ["_tcg_cpu"] + args.names()
+            else:
+                types = ["CPUState *"] + args.types()
+                names = ["_cpu"] + args.names()
+            args = Arguments(zip(types, names))
+
         return Event(name, props, fmt, args)
 
     def __repr__(self):
@@ -270,6 +283,7 @@ def _read_events(fobj):
             event_trans.name += "_trans"
             event_trans.properties += ["tcg-trans"]
             event_trans.fmt = event.fmt[0]
+            # ignore TCG arguments
             args_trans = []
             for atrans, aorig in zip(
                     event_trans.transform(tracetool.transform.TCG_2_HOST).args,
@@ -279,6 +293,12 @@ def _read_events(fobj):
             event_trans.args = Arguments(args_trans)
             event_trans = event_trans.copy()
 
+            # trace the vCPU performing the translation
+            if "vcpu" in event_trans.properties:
+                event_trans.args = Arguments(zip(
+                    ["CPUState *"] + list(event_trans.args.types()),
+                    ["_cpu"] + list(event_trans.args.names())))
+
             event_exec = event.copy()
             event_exec.name += "_exec"
             event_exec.properties += ["tcg-exec"]
diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
index 9b39430..4bdb48f 100644
--- a/scripts/tracetool/format/h.py
+++ b/scripts/tracetool/format/h.py
@@ -6,7 +6,7 @@ trace/generated-tracers.h
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2015, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -23,6 +23,8 @@ def generate(events, backend):
         '#define TRACE__GENERATED_TRACERS_H',
         '',
         '#include "qemu-common.h"',
+        '',
+        'typedef struct CPUState CPUState;',
         '')
 
     backend.generate_begin(events)
diff --git a/scripts/tracetool/format/tcg_h.py b/scripts/tracetool/format/tcg_h.py
index f676b66..222002c 100644
--- a/scripts/tracetool/format/tcg_h.py
+++ b/scripts/tracetool/format/tcg_h.py
@@ -6,14 +6,14 @@ Generate .h file for TCG code generation.
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2015, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
 __email__      = "stefanha@linux.vnet.ibm.com"
 
 
-from tracetool import out
+from tracetool import out, Arguments
 
 
 def generate(events, backend):
@@ -38,10 +38,17 @@ def generate(events, backend):
         # get the original event definition
         e = e.original.original
 
+        if "vcpu" in e.properties:
+            args_api = Arguments(zip(
+                ["CPUState *"] + e.args.types(),
+                ["_cpu"] + e.args.names()))
+        else:
+            args_api = e.args
+
         out('static inline void %(name_tcg)s(%(args)s)',
             '{',
             name_tcg=e.api(e.QEMU_TRACE_TCG),
-            args=e.args)
+            args=args_api)
 
         if "disable" not in e.properties:
             out('    %(name_trans)s(%(argnames_trans)s);',
diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py
index bc97093..92064f0 100644
--- a/scripts/tracetool/format/ust_events_c.py
+++ b/scripts/tracetool/format/ust_events_c.py
@@ -6,7 +6,7 @@ trace/generated-ust.c
 """
 
 __author__     = "Mohamad Gebai <mohamad.gebai@polymtl.ca>"
-__copyright__  = "Copyright 2012, Mohamad Gebai <mohamad.gebai@polymtl.ca>"
+__copyright__  = "Copyright 2012, 2015, Mohamad Gebai <mohamad.gebai@polymtl.ca>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -30,4 +30,6 @@ def generate(events, backend):
         ' */',
         '#pragma GCC diagnostic ignored "-Wredundant-decls"',
         '',
+        'typedef struct CPUState CPUState;',
+        '',
         '#include "generated-ust-provider.h"')

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCHv13/8] trace: [tcg] Identify events with the 'vcpu' property
  2015-10-13 17:10 [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv11/8] trace: Add support for vCPU pointers in trace events Lluís Vilanova
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv12/8] trace: Add 'vcpu' event property Lluís Vilanova
@ 2015-10-13 17:10 ` Lluís Vilanova
  2015-10-13 17:33   ` Eric Blake
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv14/8] exec: [tcg] Refactor flush of per-CPU virtual TB cache Lluís Vilanova
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 17:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stefan Hajnoczi, Markus Armbruster, Stefan Hajnoczi

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 qapi/trace.json                      |    5 +++--
 scripts/tracetool/format/events_c.py |   11 +++++++++--
 scripts/tracetool/format/events_h.py |   12 +++++++++++-
 trace/control-internal.h             |    8 +++++++-
 trace/control.h                      |    7 +++++++
 trace/event-internal.h               |    4 +++-
 trace/qmp.c                          |    2 ++
 7 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/qapi/trace.json b/qapi/trace.json
index 01b0a52..94a3a3b 100644
--- a/qapi/trace.json
+++ b/qapi/trace.json
@@ -1,6 +1,6 @@
 # -*- mode: python -*-
 #
-# Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
+# Copyright (C) 2011-2015 Lluís Vilanova <vilanova@ac.upc.edu>
 #
 # This work is licensed under the terms of the GNU GPL, version 2 or later.
 # See the COPYING file in the top-level directory.
@@ -29,11 +29,12 @@
 #
 # @name: Event name.
 # @state: Tracing state.
+# @vcpu: Whether this is a per-vCPU event.
 #
 # Since 2.2
 ##
 { 'struct': 'TraceEventInfo',
-  'data': {'name': 'str', 'state': 'TraceEventState'} }
+  'data': {'name': 'str', 'state': 'TraceEventState', 'vcpu': 'bool'} }
 
 ##
 # @trace-event-get-state:
diff --git a/scripts/tracetool/format/events_c.py b/scripts/tracetool/format/events_c.py
index 2d97fa3..693f6d7 100644
--- a/scripts/tracetool/format/events_c.py
+++ b/scripts/tracetool/format/events_c.py
@@ -6,7 +6,7 @@ trace/generated-events.c
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2015, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -27,8 +27,15 @@ def generate(events, backend):
     out('TraceEvent trace_events[TRACE_EVENT_COUNT] = {')
 
     for e in events:
-        out('    { .id = %(id)s, .name = \"%(name)s\", .sstate = %(sstate)s, .dstate = 0 },',
+        if "vcpu" in e.properties and "tcg-trans" in e.properties:
+            vcpu_id = "TRACE_CPU_" + e.name.upper()
+        else:
+            vcpu_id = "TRACE_CPU_EVENT_COUNT"
+        out('    { .id = %(id)s, .cpu_id = %(vcpu_id)s,'
+            ' .name = \"%(name)s\",'
+            ' .sstate = %(sstate)s, .dstate = 0 },',
             id = "TRACE_" + e.name.upper(),
+            vcpu_id = vcpu_id,
             name = e.name,
             sstate = "TRACE_%s_ENABLED" % e.name.upper())
 
diff --git a/scripts/tracetool/format/events_h.py b/scripts/tracetool/format/events_h.py
index 9f114a3..e89e4ab 100644
--- a/scripts/tracetool/format/events_h.py
+++ b/scripts/tracetool/format/events_h.py
@@ -6,7 +6,7 @@ trace/generated-events.h
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2015, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -34,6 +34,16 @@ def generate(events, backend):
     out('    TRACE_EVENT_COUNT',
         '} TraceEventID;')
 
+    # per-vCPU event identifiers
+    out('typedef enum {')
+
+    for e in events:
+        if "vcpu" in e.properties and "tcg-trans" in e.properties:
+            out('    TRACE_CPU_%s,' % e.name.upper())
+
+    out('    TRACE_CPU_EVENT_COUNT',
+        '} TraceEventCPUID;')
+
     # static state
     for e in events:
         if 'disable' in e.properties:
diff --git a/trace/control-internal.h b/trace/control-internal.h
index 5a8df28..70e55df 100644
--- a/trace/control-internal.h
+++ b/trace/control-internal.h
@@ -1,7 +1,7 @@
 /*
  * Interface for configuring and controlling the state of tracing events.
  *
- * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2011-2015 Lluís Vilanova <vilanova@ac.upc.edu>
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -39,6 +39,12 @@ static inline TraceEventID trace_event_get_id(TraceEvent *ev)
     return ev->id;
 }
 
+static inline TraceEventCPUID trace_event_get_cpu_id(TraceEvent *ev)
+{
+    assert(ev != NULL);
+    return ev->cpu_id;
+}
+
 static inline const char * trace_event_get_name(TraceEvent *ev)
 {
     assert(ev != NULL);
diff --git a/trace/control.h b/trace/control.h
index 1a78a7b..c0680c7 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -89,6 +89,13 @@ static TraceEventID trace_event_count(void);
 static TraceEventID trace_event_get_id(TraceEvent *ev);
 
 /**
+ * trace_event_get_cpu_id:
+ *
+ * Get the per-vCPU identifier of an event.
+ */
+static TraceEventCPUID trace_event_get_cpu_id(TraceEvent *ev);
+
+/**
  * trace_event_get_name:
  *
  * Get the name of an event.
diff --git a/trace/event-internal.h b/trace/event-internal.h
index b2310d9..ae18b48 100644
--- a/trace/event-internal.h
+++ b/trace/event-internal.h
@@ -1,7 +1,7 @@
 /*
  * Interface for configuring and controlling the state of tracing events.
  *
- * Copyright (C) 2012 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2012-2015 Lluís Vilanova <vilanova@ac.upc.edu>
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -16,6 +16,7 @@
 /**
  * TraceEvent:
  * @id: Unique event identifier.
+ * @cpu_id: Unique per-vCPU event identifier.
  * @name: Event name.
  * @sstate: Static tracing state.
  * @dstate: Dynamic tracing state.
@@ -24,6 +25,7 @@
  */
 typedef struct TraceEvent {
     TraceEventID id;
+    TraceEventCPUID cpu_id;
     const char * name;
     const bool sstate;
     bool dstate;
diff --git a/trace/qmp.c b/trace/qmp.c
index 0b19489..a669698 100644
--- a/trace/qmp.c
+++ b/trace/qmp.c
@@ -22,6 +22,8 @@ TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp)
     while ((ev = trace_event_pattern(name, ev)) != NULL) {
         TraceEventInfoList *elem = g_new(TraceEventInfoList, 1);
         elem->value = g_new(TraceEventInfo, 1);
+        elem->value->vcpu =
+            trace_event_get_cpu_id(ev) == TRACE_CPU_EVENT_COUNT ? false : true;
         elem->value->name = g_strdup(trace_event_get_name(ev));
         if (!trace_event_get_state_static(ev)) {
             elem->value->state = TRACE_EVENT_STATE_UNAVAILABLE;

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCHv14/8] exec: [tcg] Refactor flush of per-CPU virtual TB cache
  2015-10-13 17:10 [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
                   ` (2 preceding siblings ...)
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv13/8] trace: [tcg] Identify events with the 'vcpu' property Lluís Vilanova
@ 2015-10-13 17:10 ` Lluís Vilanova
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv15/8] exec: [ŧcg] Use multiple physical TB caches Lluís Vilanova
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 17:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stefan Hajnoczi

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 cputlb.c                |    2 +-
 include/exec/exec-all.h |    6 ++++++
 translate-all.c         |    7 ++++++-
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/cputlb.c b/cputlb.c
index bf1d50a..74bf989 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -61,7 +61,7 @@ void tlb_flush(CPUState *cpu, int flush_global)
 
     memset(env->tlb_table, -1, sizeof(env->tlb_table));
     memset(env->tlb_v_table, -1, sizeof(env->tlb_v_table));
-    memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
+    tb_flush_jmp_cache_all(cpu);
 
     env->vtlb_index = 0;
     env->tlb_flush_addr = -1;
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index a63fd60..de9ffa0 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -239,6 +239,12 @@ struct TBContext {
 };
 
 void tb_free(TranslationBlock *tb);
+/**
+ * tb_flush_jmp_cache_all:
+ *
+ * Flush the virtual translation block cache.
+ */
+void tb_flush_jmp_cache_all(CPUState *env);
 void tb_flush(CPUState *cpu);
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
 
diff --git a/translate-all.c b/translate-all.c
index 333eba4..e5eb6db 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -844,7 +844,7 @@ void tb_flush(CPUState *cpu)
     tcg_ctx.tb_ctx.nb_tbs = 0;
 
     CPU_FOREACH(cpu) {
-        memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
+        tb_flush_jmp_cache_all(cpu);
     }
 
     memset(tcg_ctx.tb_ctx.tb_phys_hash, 0, sizeof(tcg_ctx.tb_ctx.tb_phys_hash));
@@ -1584,6 +1584,11 @@ void tb_check_watchpoint(CPUState *cpu)
     }
 }
 
+void tb_flush_jmp_cache_all(CPUState *cpu)
+{
+    memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
+}
+
 #ifndef CONFIG_USER_ONLY
 /* in deterministic execution mode, instructions doing device I/Os
    must be at the end of the TB */

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCHv15/8] exec: [ŧcg] Use multiple physical TB caches
  2015-10-13 17:10 [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
                   ` (3 preceding siblings ...)
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv14/8] exec: [tcg] Refactor flush of per-CPU virtual TB cache Lluís Vilanova
@ 2015-10-13 17:10 ` Lluís Vilanova
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv16/8] exec: [tcg] Track which vCPU is performing translation and execution Lluís Vilanova
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 17:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stefan Hajnoczi, Andreas Färber

The physical translation block cache is split into as many caches as wanted, and
the virtual TB cache on each guest CPU uses a (potentially) different physical
TB cache.

This is later exploited to support different tracing event states on a per-vCPU
basis.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 cpu-exec.c              |   17 +++++
 include/exec/exec-all.h |   10 +++
 include/qom/cpu.h       |    5 ++
 qom/cpu.c               |    9 +++
 translate-all.c         |  146 +++++++++++++++++++++++++++++++++++++++++------
 translate-all.h         |   49 ++++++++++++++++
 6 files changed, 214 insertions(+), 22 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 8fd56a6..b47d57b 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -27,6 +27,7 @@
 #include "exec/address-spaces.h"
 #include "qemu/rcu.h"
 #include "exec/tb-hash.h"
+#include "translate-all.h"
 #if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
 #include "hw/i386/apic.h"
 #endif
@@ -222,7 +223,7 @@ static TranslationBlock *tb_find_physical(CPUState *cpu,
     phys_pc = get_page_addr_code(env, pc);
     phys_page1 = phys_pc & TARGET_PAGE_MASK;
     h = tb_phys_hash_func(phys_pc);
-    ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[h];
+    ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[cpu->tb_phys_idx][h];
     for(;;) {
         tb = *ptb1;
         if (!tb) {
@@ -251,8 +252,8 @@ static TranslationBlock *tb_find_physical(CPUState *cpu,
 
     /* Move the TB to the head of the list */
     *ptb1 = tb->phys_hash_next;
-    tb->phys_hash_next = tcg_ctx.tb_ctx.tb_phys_hash[h];
-    tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
+    tb->phys_hash_next = tcg_ctx.tb_ctx.tb_phys_hash[cpu->tb_phys_idx][h];
+    tcg_ctx.tb_ctx.tb_phys_hash[cpu->tb_phys_idx][h] = tb;
     return tb;
 }
 
@@ -459,6 +460,16 @@ int cpu_exec(CPUState *cpu)
                     cpu->exception_index = EXCP_INTERRUPT;
                     cpu_loop_exit(cpu);
                 }
+                if (unlikely(tcg_ctx.tb_ctx.tb_phys_hash_size_req !=
+                             tcg_ctx.tb_ctx.tb_phys_hash_size)) {
+                    if (tb_caches_apply() < 0) {
+                        next_tb = 0;
+                    }
+                }
+                if (unlikely(cpu->tb_phys_idx != cpu->tb_phys_idx_req)) {
+                    cpu_tb_cache_apply(cpu);
+                    next_tb = 0;
+                }
                 tb_lock();
                 tb = tb_find_fast(cpu);
                 /* Note: we do it here to avoid a gcc bug on Mac OS X when
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index de9ffa0..82aa1d0 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -179,6 +179,10 @@ static inline void tlb_flush_by_mmuidx(CPUState *cpu, ...)
 #define USE_DIRECT_JUMP
 #endif
 
+/**
+ * TranslationBlock:
+ * @phys_idx: Index of physical TB cache where this TB has been allocated.
+ */
 struct TranslationBlock {
     target_ulong pc;   /* simulated PC corresponding to this block (EIP + CS base) */
     target_ulong cs_base; /* CS base for this block */
@@ -217,6 +221,8 @@ struct TranslationBlock {
        jmp_first */
     struct TranslationBlock *jmp_next[2];
     struct TranslationBlock *jmp_first;
+
+    unsigned int phys_idx;
 };
 
 #include "qemu/thread.h"
@@ -226,7 +232,9 @@ typedef struct TBContext TBContext;
 struct TBContext {
 
     TranslationBlock *tbs;
-    TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
+    TranslationBlock ***tb_phys_hash;
+    size_t tb_phys_hash_size;
+    size_t tb_phys_hash_size_req;
     int nb_tbs;
     /* any access to the tbs or the page table must use this lock */
     QemuMutex tb_lock;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index b613ff0..743e13b 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -246,6 +246,8 @@ struct kvm_run;
  * @kvm_fd: vCPU file descriptor for KVM.
  * @work_mutex: Lock to prevent multiple access to queued_work_*.
  * @queued_work_first: First asynchronous work pending.
+ * @tb_phys_idx: Index of current phsyical TB cache.
+ * @tb_phys_idx_req: Index of requested phsyical TB cache.
  *
  * State of one CPU core or thread.
  */
@@ -311,6 +313,9 @@ struct CPUState {
     struct KVMState *kvm_state;
     struct kvm_run *kvm_run;
 
+    unsigned int tb_phys_idx;
+    unsigned int tb_phys_idx_req;
+
     /* TODO Move common fields from CPUArchState here. */
     int cpu_index; /* used by alpha TCG */
     uint32_t halted; /* used by alpha, cris, ppc TCG */
diff --git a/qom/cpu.c b/qom/cpu.c
index fb80d13..bb7a618 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -363,6 +363,14 @@ static void cpu_class_init(ObjectClass *klass, void *data)
     dc->cannot_instantiate_with_device_add_yet = true;
 }
 
+static void cpu_init(Object *obj)
+{
+    CPUState *cpu = CPU(obj);
+
+    cpu->tb_phys_idx = 0;
+    cpu->tb_phys_idx_req = 0;
+}
+
 static const TypeInfo cpu_type_info = {
     .name = TYPE_CPU,
     .parent = TYPE_DEVICE,
@@ -372,6 +380,7 @@ static const TypeInfo cpu_type_info = {
     .abstract = true,
     .class_size = sizeof(CPUClass),
     .class_init = cpu_class_init,
+    .instance_init = cpu_init,
 };
 
 static void cpu_register_types(void)
diff --git a/translate-all.c b/translate-all.c
index e5eb6db..5df7da5 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -163,9 +163,22 @@ static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
                          tb_page_addr_t phys_page2);
 static TranslationBlock *tb_find_pc(uintptr_t tc_ptr);
 
+static void tb_phys_cache_alloc(unsigned int idx)
+{
+    size_t size = sizeof(tcg_ctx.tb_ctx.tb_phys_hash[0][0]) *
+        CODE_GEN_PHYS_HASH_SIZE;
+    tcg_ctx.tb_ctx.tb_phys_hash[idx] = malloc(size);
+    memset(tcg_ctx.tb_ctx.tb_phys_hash[idx], 0, size);
+}
+
 void cpu_gen_init(void)
 {
     tcg_context_init(&tcg_ctx); 
+
+    tcg_ctx.tb_ctx.tb_phys_hash_size = 0;
+    tcg_ctx.tb_ctx.tb_phys_hash_size_req = 1;
+    tcg_ctx.tb_ctx.tb_phys_hash = NULL;
+    tb_caches_apply();
 }
 
 /* Encode VAL as a signed leb128 sequence at P.
@@ -847,7 +860,12 @@ void tb_flush(CPUState *cpu)
         tb_flush_jmp_cache_all(cpu);
     }
 
-    memset(tcg_ctx.tb_ctx.tb_phys_hash, 0, sizeof(tcg_ctx.tb_ctx.tb_phys_hash));
+    unsigned int cache;
+    for (cache = 0; cache < tb_caches_get(); cache++) {
+        memset(tcg_ctx.tb_ctx.tb_phys_hash[cache], 0,
+               (sizeof(tcg_ctx.tb_ctx.tb_phys_hash[0][0]) *
+                CODE_GEN_PHYS_HASH_SIZE));
+    }
     page_flush_tb();
 
     tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer;
@@ -861,16 +879,21 @@ void tb_flush(CPUState *cpu)
 static void tb_invalidate_check(target_ulong address)
 {
     TranslationBlock *tb;
+    unsigned int cache;
     int i;
 
     address &= TARGET_PAGE_MASK;
-    for (i = 0; i < CODE_GEN_PHYS_HASH_SIZE; i++) {
-        for (tb = tb_ctx.tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
-            if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
-                  address >= tb->pc + tb->size)) {
-                printf("ERROR invalidate: address=" TARGET_FMT_lx
-                       " PC=%08lx size=%04x\n",
-                       address, (long)tb->pc, tb->size);
+    for (cache = 0; cache < tb_caches_get(); cache++) {
+        for (i = 0; i < CODE_GEN_PHYS_HASH_SIZE; i++) {
+            for (tb = tb_phys_hash[cache][i];
+                 tb != NULL;
+                 tb = tb->phys_hash_next) {
+                if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
+                      address >= tb->pc + tb->size)) {
+                    printf("ERROR invalidate: address=" TARGET_FMT_lx
+                           " PC=%08lx size=%04x\n",
+                           address, (long)tb->pc, tb->size);
+                }
             }
         }
     }
@@ -880,16 +903,20 @@ static void tb_invalidate_check(target_ulong address)
 static void tb_page_check(void)
 {
     TranslationBlock *tb;
+    unsigned int cache;
     int i, flags1, flags2;
 
-    for (i = 0; i < CODE_GEN_PHYS_HASH_SIZE; i++) {
-        for (tb = tcg_ctx.tb_ctx.tb_phys_hash[i]; tb != NULL;
-                tb = tb->phys_hash_next) {
-            flags1 = page_get_flags(tb->pc);
-            flags2 = page_get_flags(tb->pc + tb->size - 1);
-            if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
-                printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
-                       (long)tb->pc, tb->size, flags1, flags2);
+    for (cache = 0; cache < tb_caches_get(); cache++) {
+        for (i = 0; i < CODE_GEN_PHYS_HASH_SIZE; i++) {
+            for (tb = tb_phys_hash[cache][i];
+                 tb != NULL;
+                 tb = tb->phys_hash_next) {
+                flags1 = page_get_flags(tb->pc);
+                flags2 = page_get_flags(tb->pc + tb->size - 1);
+                if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
+                    printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
+                           (long)tb->pc, tb->size, flags1, flags2);
+                }
             }
         }
     }
@@ -976,7 +1003,7 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
     /* remove the TB from the hash list */
     phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
     h = tb_phys_hash_func(phys_pc);
-    tb_hash_remove(&tcg_ctx.tb_ctx.tb_phys_hash[h], tb);
+    tb_hash_remove(&tcg_ctx.tb_ctx.tb_phys_hash[tb->phys_idx][h], tb);
 
     /* remove the TB from the page list */
     if (tb->page_addr[0] != page_addr) {
@@ -1051,6 +1078,86 @@ static void build_page_bitmap(PageDesc *p)
     }
 }
 
+size_t tb_caches_get(void)
+{
+    return tcg_ctx.tb_ctx.tb_phys_hash_size;
+}
+
+void tb_caches_set(size_t count)
+{
+    assert(count > 0);
+#ifndef NDEBUG
+    /* ensure no CPU is going to switch/stay in one of the removed caches */
+    CPUState *cpu;
+    CPU_FOREACH(cpu) {
+        assert(cpu->tb_phys_idx_req < count);
+    }
+#endif
+    tcg_ctx.tb_ctx.tb_phys_hash_size_req = count;
+}
+
+int tb_caches_apply(void)
+{
+    struct TBContext *tb_ctx = &tcg_ctx.tb_ctx;
+
+    if (likely(tb_ctx->tb_phys_hash_size_req == tb_ctx->tb_phys_hash_size)) {
+        return 0;
+    }
+
+    int res = tb_ctx->tb_phys_hash_size_req < tb_ctx->tb_phys_hash_size ?
+        -1 : 1;
+
+    if (res < 0) {
+        int i;
+        for (i = tb_ctx->tb_phys_hash_size_req;
+             i < tb_ctx->tb_phys_hash_size;
+             i++) {
+            free(tb_ctx->tb_phys_hash[i]);
+        }
+
+        CPUState *cpu;
+        CPU_FOREACH(cpu) {
+            if (cpu->tb_phys_idx >= tb_ctx->tb_phys_hash_size_req) {
+                fprintf(stderr,
+                        "CPU %d is using a deleted TB cache\n", cpu->cpu_index);
+                exit(1);
+            }
+        }
+    }
+
+    size_t size = sizeof(tb_ctx->tb_phys_hash[0]) *
+        tb_ctx->tb_phys_hash_size_req;
+    tb_ctx->tb_phys_hash = realloc(tb_ctx->tb_phys_hash, size);
+    int i;
+    for (i = tb_ctx->tb_phys_hash_size;
+         i < tb_ctx->tb_phys_hash_size_req;
+         i++) {
+        tb_phys_cache_alloc(i);
+    }
+
+    tb_ctx->tb_phys_hash_size = tb_ctx->tb_phys_hash_size_req;
+    return res;
+}
+
+unsigned int cpu_tb_cache_get(CPUState *cpu)
+{
+    return cpu->tb_phys_idx;
+}
+
+void cpu_tb_cache_set(CPUState *cpu, unsigned int index)
+{
+    assert(index < tcg_ctx.tb_ctx.tb_phys_hash_size_req);
+    cpu->tb_phys_idx_req = index;
+    cpu->tcg_exit_req = true;
+}
+
+void cpu_tb_cache_apply(CPUState *cpu)
+{
+    cpu->tb_phys_idx = cpu->tb_phys_idx_req;
+    tb_flush_jmp_cache_all(cpu);
+}
+
+
 /* Called with mmap_lock held for user mode emulation.  */
 TranslationBlock *tb_gen_code(CPUState *cpu,
                               target_ulong pc, target_ulong cs_base,
@@ -1088,6 +1195,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
     tb->cs_base = cs_base;
     tb->flags = flags;
     tb->cflags = cflags;
+    tb->phys_idx = ENV_GET_CPU(env)->tb_phys_idx;
 
 #ifdef CONFIG_PROFILER
     tcg_ctx.tb_count1++; /* includes aborted translations because of
@@ -1478,7 +1586,7 @@ static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
 
     /* add in the physical hash table */
     h = tb_phys_hash_func(phys_pc);
-    ptb = &tcg_ctx.tb_ctx.tb_phys_hash[h];
+    ptb = &tcg_ctx.tb_ctx.tb_phys_hash[tb->phys_idx][h];
     tb->phys_hash_next = *ptb;
     *ptb = tb;
 
@@ -1641,6 +1749,8 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
     pc = tb->pc;
     cs_base = tb->cs_base;
     flags = tb->flags;
+    /* XXX: It is OK to invalidate only this TB, as this is the one triggering
+     * the memory access */
     tb_phys_invalidate(tb, -1);
     if (tb->cflags & CF_NOCACHE) {
         if (tb->orig_tb) {
diff --git a/translate-all.h b/translate-all.h
index 0384640..d7ad063 100644
--- a/translate-all.h
+++ b/translate-all.h
@@ -19,6 +19,55 @@
 #ifndef TRANSLATE_ALL_H
 #define TRANSLATE_ALL_H
 
+
+/**
+ * tb_caches_get:
+ *
+ * Number of physical TB caches.
+ */
+size_t tb_caches_get(void);
+/**
+ * tb_caches_set:
+ *
+ * Request a new number of physical TB caches.
+ */
+void tb_caches_set(size_t count);
+/**
+ * tb_caches_apply:
+ *
+ * Apply the changes for a tb_caches_set() request.
+ *
+ * Returns: -1/1 if the number of caches has been shrinked/grown; 0 otherwise.
+ *
+ * Note: All TBs of eliminated caches are invalidated.
+ *
+ * Precondition: No vCPU uses any of the caches that will be removed (if any;
+ *               see cpu_tb_cache_set() and tb_caches_set()).
+ */
+int tb_caches_apply(void);
+/**
+ * cpu_tb_cache_get:
+ *
+ * Get the physical TB cache index for the given CPU.
+ */
+unsigned int cpu_tb_cache_get(CPUState *cpu);
+/**
+ * cpu_tb_cache_set:
+ *
+ * Set the physical TB cache index for the given CPU.
+ *
+ * Will have effect at the beginning of the next executed TB.
+ */
+void cpu_tb_cache_set(CPUState *cpu, unsigned int index);
+/**
+ * cpu_tb_cache_apply:
+ *
+ * Apply the changes for a cpu_tb_cache_set() request.
+ *
+ * Note: Invalidates the jump cache of the given CPU.
+ */
+void cpu_tb_cache_apply(CPUState *env);
+
 /* translate-all.c */
 void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len);
 void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCHv16/8] exec: [tcg] Track which vCPU is performing translation and execution
  2015-10-13 17:10 [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
                   ` (4 preceding siblings ...)
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv15/8] exec: [ŧcg] Use multiple physical TB caches Lluís Vilanova
@ 2015-10-13 17:10 ` Lluís Vilanova
  2015-10-13 17:11 ` [Qemu-devel] [PATCHv17/8] [trivial] Track when QEMU has finished initialization Lluís Vilanova
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 17:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Guan Xuetao, Eduardo Habkost, Stefan Hajnoczi,
	Anthony Green, Mark Cave-Ayland, Jia Liu, Alexander Graf,
	Blue Swirl, Max Filippov, Michael Walle, open list:PowerPC,
	Edgar E. Iglesias, Paolo Bonzini, Bastian Koppelmann, Leon Alrae,
	Aurelien Jarno, Richard Henderson

Information is tracked inside the TCGContext structure.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 target-alpha/translate.c      |    1 +
 target-arm/translate.c        |    1 +
 target-cris/translate.c       |    1 +
 target-cris/translate_v10.c   |    1 +
 target-i386/translate.c       |    1 +
 target-lm32/translate.c       |    1 +
 target-m68k/translate.c       |    1 +
 target-microblaze/translate.c |    1 +
 target-mips/translate.c       |    1 +
 target-moxie/translate.c      |    1 +
 target-openrisc/translate.c   |    1 +
 target-ppc/translate.c        |    1 +
 target-s390x/translate.c      |    1 +
 target-sh4/translate.c        |    1 +
 target-sparc/translate.c      |    1 +
 target-tilegx/translate.c     |    1 +
 target-tricore/translate.c    |    1 +
 target-unicore32/translate.c  |    1 +
 target-xtensa/translate.c     |    1 +
 tcg/tcg.h                     |    4 ++++
 translate-all.c               |    2 ++
 21 files changed, 25 insertions(+)

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 6154519..9395813 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -148,6 +148,7 @@ void alpha_translate_init(void)
     done_init = 1;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
 
     for (i = 0; i < 31; i++) {
         cpu_std_ir[i] = tcg_global_mem_new_i64(TCG_AREG0,
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 7dc7862..61803ca 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -87,6 +87,7 @@ void arm_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
 
     for (i = 0; i < 16; i++) {
         cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 9dd5c5f..576a5c6 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3355,6 +3355,7 @@ void cris_initialize_tcg(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
     cc_x = tcg_global_mem_new(TCG_AREG0,
                               offsetof(CPUCRISState, cc_x), "cc_x");
     cc_src = tcg_global_mem_new(TCG_AREG0,
diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
index 3ab1c39..1ef8995 100644
--- a/target-cris/translate_v10.c
+++ b/target-cris/translate_v10.c
@@ -1249,6 +1249,7 @@ void cris_initialize_crisv10_tcg(void)
 	int i;
 
 	cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+        tcg_ctx.tcg_env = cpu_env;
 	cc_x = tcg_global_mem_new(TCG_AREG0,
 				  offsetof(CPUCRISState, cc_x), "cc_x");
 	cc_src = tcg_global_mem_new(TCG_AREG0,
diff --git a/target-i386/translate.c b/target-i386/translate.c
index e191224..c304c87 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7818,6 +7818,7 @@ void optimize_flags_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
     cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
                                        offsetof(CPUX86State, cc_op), "cc_op");
     cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 45abe53..a74847d 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1184,6 +1184,7 @@ void lm32_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
 
     for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
         cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index e3ee9e0..a3f03b7 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -91,6 +91,7 @@ void m68k_tcg_init(void)
                                                  "EXCEPTION");
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
 
     p = cpu_reg_names;
     for (i = 0; i < 8; i++) {
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 6b0915e..2d73b64 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1862,6 +1862,7 @@ void mb_tcg_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
 
     env_debug = tcg_global_mem_new(TCG_AREG0, 
                     offsetof(CPUMBState, debug),
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 9ffb100..dc44458 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -19783,6 +19783,7 @@ void mips_tcg_init(void)
         return;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
     TCGV_UNUSED(cpu_gpr[0]);
     for (i = 1; i < 32; i++)
         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
diff --git a/target-moxie/translate.c b/target-moxie/translate.c
index f8c70cb..08acd07 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -109,6 +109,7 @@ void moxie_translate_init(void)
         return;
     }
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
     cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
                                     offsetof(CPUMoxieState, pc), "$pc");
     for (i = 0; i < 16; i++)
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index c122c20..7cb352f 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -77,6 +77,7 @@ void openrisc_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
     cpu_sr = tcg_global_mem_new(TCG_AREG0,
                                 offsetof(CPUOpenRISCState, sr), "sr");
     env_flags = tcg_global_mem_new_i32(TCG_AREG0,
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index ff40c6b..78e763f 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -85,6 +85,7 @@ void ppc_translate_init(void)
         return;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
 
     p = cpu_reg_names;
     cpu_reg_names_size = sizeof(cpu_reg_names);
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 7e549d8..76f4cef 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -166,6 +166,7 @@ void s390x_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
     psw_addr = tcg_global_mem_new_i64(TCG_AREG0,
                                       offsetof(CPUS390XState, psw.addr),
                                       "psw_addr");
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 7fb4900..5d6c1ec 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -98,6 +98,7 @@ void sh4_translate_init(void)
         return;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
 
     for (i = 0; i < 24; i++)
         cpu_gregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 3d5d150..5bdf285 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5344,6 +5344,7 @@ void gen_intermediate_code_init(CPUSPARCState *env)
         inited = 1;
 
         cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+        tcg_ctx.tcg_env = cpu_env;
         cpu_regwptr = tcg_global_mem_new_ptr(TCG_AREG0,
                                              offsetof(CPUSPARCState, regwptr),
                                              "regwptr");
diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 0cd6700..23e4d1a 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -2434,6 +2434,7 @@ void tilegx_tcg_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
     cpu_pc = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUTLGState, pc), "pc");
     for (i = 0; i < TILEGX_R_COUNT; i++) {
         cpu_regs[i] = tcg_global_mem_new_i64(TCG_AREG0,
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 655db75..a56bf2c 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -8366,6 +8366,7 @@ void tricore_tcg_init(void)
         return;
     }
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
     /* reg init */
     for (i = 0 ; i < 16 ; i++) {
         cpu_gpr_a[i] = tcg_global_mem_new(TCG_AREG0,
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 6ba52c2..7d68232 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -72,6 +72,7 @@ void uc32_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
 
     for (i = 0; i < 32; i++) {
         cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index c6d7658..b4a00c1 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -217,6 +217,7 @@ void xtensa_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    tcg_ctx.tcg_env = cpu_env;
     cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
             offsetof(CPUXtensaState, pc), "pc");
 
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 1585551..92d4604 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -572,6 +572,10 @@ struct TCGContext {
 
     TBContext tb_ctx;
 
+    /* Track vCPU triggering events */
+    CPUState *cpu;                      /* *_trans */
+    TCGv_cpu tcg_env;                   /* *_exec  */
+
     /* The TCGBackendData structure is private to tcg-target.c.  */
     struct TCGBackendData *be;
 
diff --git a/translate-all.c b/translate-all.c
index 5df7da5..5ae64d6 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1203,6 +1203,8 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
     ti = profile_getclock();
 #endif
 
+    tcg_ctx.cpu = ENV_GET_CPU(env);
+
     tcg_func_start(&tcg_ctx);
 
     gen_intermediate_code(env, tb);

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCHv17/8] [trivial] Track when QEMU has finished initialization
  2015-10-13 17:10 [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
                   ` (5 preceding siblings ...)
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv16/8] exec: [tcg] Track which vCPU is performing translation and execution Lluís Vilanova
@ 2015-10-13 17:11 ` Lluís Vilanova
  2015-10-13 18:56   ` Markus Armbruster
  2015-10-13 17:11 ` [Qemu-devel] [PATCHv18/8] trace: [tcg] Add per-vCPU tracing states for events with the 'vcpu' property Lluís Vilanova
  2015-10-13 17:26 ` [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
  8 siblings, 1 reply; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 17:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Stefan Hajnoczi, Riku Voipio, Paolo Bonzini

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 Makefile.objs            |    2 +-
 bsd-user/main.c          |    1 +
 include/qemu-common.h    |    3 +++
 linux-user/main.c        |    1 +
 qemu-common.c            |   14 ++++++++++++++
 stubs/Makefile.objs      |    1 +
 stubs/qemu-common-stub.c |   21 +++++++++++++++++++++
 vl.c                     |    2 ++
 8 files changed, 44 insertions(+), 1 deletion(-)
 create mode 100644 qemu-common.c
 create mode 100644 stubs/qemu-common-stub.c

diff --git a/Makefile.objs b/Makefile.objs
index bc43e5c..e1d7b25 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -2,7 +2,7 @@
 # Common libraries for tools and emulators
 stub-obj-y = stubs/
 util-obj-y = util/ qobject/ qapi/
-util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o
+util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o qemu-common.o
 
 #######################################################################
 # block-obj-y is code used by both qemu system emulation and qemu-img
diff --git a/bsd-user/main.c b/bsd-user/main.c
index f0a1268..43f85e6 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -1121,6 +1121,7 @@ int main(int argc, char **argv)
         gdbserver_start (gdbstub_port);
         gdb_handlesig(cpu, 0);
     }
+    qemu_initialized = true;
     cpu_loop(env);
     /* never exits */
     return 0;
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 0bd212b..33f6909 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -35,6 +35,9 @@
 # error Unknown pointer size
 #endif
 
+/* Whether the system has finished initializing */
+extern bool qemu_initialized;
+
 void cpu_ticks_init(void);
 
 /* icount */
diff --git a/linux-user/main.c b/linux-user/main.c
index 1f60ff2..9bd2912 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -4663,6 +4663,7 @@ int main(int argc, char **argv, char **envp)
         }
         gdb_handlesig(cpu, 0);
     }
+    qemu_initialized = true;
     cpu_loop(env);
     /* never exits */
     return 0;
diff --git a/qemu-common.c b/qemu-common.c
new file mode 100644
index 0000000..4b5ca1a
--- /dev/null
+++ b/qemu-common.c
@@ -0,0 +1,14 @@
+/*
+ * Common symbol definitions for all tools and targets.
+ *
+ * Copyright (C) 2011-2015 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+*/
+
+#include "qemu-common.h"
+
+
+/* Whether QEMU has been initialized. */
+bool qemu_initialized;
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 85e4e81..259504f 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -39,3 +39,4 @@ stub-obj-y += cpus.o
 stub-obj-y += kvm.o
 stub-obj-y += qmp_pc_dimm_device_list.o
 stub-obj-y += target-monitor-defs.o
+stub-obj-y += qemu-common-stub.o
diff --git a/stubs/qemu-common-stub.c b/stubs/qemu-common-stub.c
new file mode 100644
index 0000000..f34f019
--- /dev/null
+++ b/stubs/qemu-common-stub.c
@@ -0,0 +1,21 @@
+/*
+ * Common symbol definitions for all tools and targets.
+ *
+ * Copyright (C) 2011-2015 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+*/
+
+#include "qemu-common.h"
+#include <qemu/module.h>
+
+
+static void do_qemu_initialized_init(void)
+{
+    /* Tools always consider QEMU as inited */
+    qemu_initialized = true;
+}
+
+/* Block is always inited on both tools (and targets) */
+block_init(do_qemu_initialized_init);
diff --git a/vl.c b/vl.c
index f2bd8d2..aae8d47 100644
--- a/vl.c
+++ b/vl.c
@@ -4637,6 +4637,8 @@ int main(int argc, char **argv, char **envp)
         }
     }
 
+    qemu_initialized = true;
+
     main_loop();
     bdrv_close_all();
     pause_all_vcpus();

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCHv18/8] trace: [tcg] Add per-vCPU tracing states for events with the 'vcpu' property
  2015-10-13 17:10 [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
                   ` (6 preceding siblings ...)
  2015-10-13 17:11 ` [Qemu-devel] [PATCHv17/8] [trivial] Track when QEMU has finished initialization Lluís Vilanova
@ 2015-10-13 17:11 ` Lluís Vilanova
  2015-10-13 17:50   ` Eric Blake
  2015-10-16  9:19   ` Stefan Hajnoczi
  2015-10-13 17:26 ` [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
  8 siblings, 2 replies; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 17:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Stefan Hajnoczi, Markus Armbruster, Gerd Hoffmann,
	Stefan Hajnoczi, Andreas Färber

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 Makefile.objs                            |    1 
 include/qom/cpu.h                        |    5 +
 qapi/trace.json                          |   31 +++++++
 qmp-commands.hx                          |   27 ++++++
 qom/cpu.c                                |   12 +++
 scripts/tracetool/format/tcg_h.py        |    6 +
 scripts/tracetool/format/tcg_helper_c.py |   11 ++-
 trace/Makefile.objs                      |    2 
 trace/control-internal.h                 |   17 +++-
 trace/control-stub.c                     |   29 +++++++
 trace/control-target.c                   |   53 +++++++++++++
 trace/control.h                          |   53 ++++++++++++-
 trace/qmp.c                              |  127 ++++++++++++++++++++++++++++--
 translate-all.c                          |    1 
 ui/Makefile.objs                         |    2 
 15 files changed, 357 insertions(+), 20 deletions(-)
 create mode 100644 trace/control-stub.c
 create mode 100644 trace/control-target.c

diff --git a/Makefile.objs b/Makefile.objs
index e1d7b25..99f9d2a 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -100,6 +100,7 @@ version-lobj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.lo
 # tracing
 util-obj-y +=  trace/
 target-obj-y += trace/
+stub-obj-y += trace/
 
 ######################################################################
 # guest agent
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 743e13b..94a4c1d 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -29,6 +29,7 @@
 #include "qemu/queue.h"
 #include "qemu/thread.h"
 #include "qemu/typedefs.h"
+#include "trace/generated-events.h"
 
 typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
                                      void *opaque);
@@ -316,6 +317,10 @@ struct CPUState {
     unsigned int tb_phys_idx;
     unsigned int tb_phys_idx_req;
 
+    /* Ensure 'tb_phys_idx' can encode event states as a bitmask */
+    bool too_many_tcg_vcpu_events[
+        TRACE_CPU_EVENT_COUNT > sizeof(unsigned int)*8 ? -1 : 0];
+
     /* TODO Move common fields from CPUArchState here. */
     int cpu_index; /* used by alpha TCG */
     uint32_t halted; /* used by alpha, cris, ppc TCG */
diff --git a/qapi/trace.json b/qapi/trace.json
index 94a3a3b..369f4aa 100644
--- a/qapi/trace.json
+++ b/qapi/trace.json
@@ -64,3 +64,34 @@
 ##
 { 'command': 'trace-event-set-state',
   'data': {'name': 'str', 'enable': 'bool', '*ignore-unavailable': 'bool'} }
+
+##
+# @trace-event-get-cpu-state:
+#
+# Query the state of events in a given vCPU.
+#
+# @name: Event name pattern.
+# @vcpu: The vCPU to check.
+#
+# Returns: @TraceEventInfo of the matched events
+#
+# Since 2.2
+##
+{ 'command': 'trace-event-get-cpu-state',
+  'data': {'name': 'str', 'vcpu': 'int'},
+  'returns': ['TraceEventInfo'] }
+
+##
+# @trace-event-set-cpu-state:
+#
+# Set the dynamic state of events in a given vCPU.
+#
+# @name: Event name pattern.
+# @vcpu: The vCPU to act upon.
+# @enable: Whether to enable tracing.
+# @ignore-unavailable: #optional Do not match unavailable events with @name.
+#
+# Since 2.2
+##
+{ 'command': 'trace-event-set-cpu-state',
+  'data': {'name': 'str', 'vcpu': 'int', 'enable': 'bool', '*ignore-unavailable': 'bool'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index d2ba800..b6b55af 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -4189,6 +4189,33 @@ Move mouse pointer to absolute coordinates (20000, 400).
                { "type": "abs", "data" : { "axis": "X", "value" : 20000 } },
                { "type": "abs", "data" : { "axis": "Y", "value" : 400 } } ] } }
 <- { "return": {} }
+EQMP
+
+    {
+        .name       = "trace-event-get-cpu-state",
+        .args_type  = "name:s,vcpu:i",
+        .mhandler.cmd_new = qmp_marshal_trace_event_get_cpu_state,
+    },
+
+SQMP
+trace-event-get-state
+---------------------
+
+Query the state of events in a given vCPU.
+
+EQMP
+
+    {
+        .name       = "trace-event-set-cpu-state",
+        .args_type  = "name:s,vcpu:i,enable:b,ignore-unavailable:b?",
+        .mhandler.cmd_new = qmp_marshal_trace_event_set_cpu_state,
+    },
+
+SQMP
+trace-event-set-state
+---------------------
+
+Set the state of events in a given vCPU.
 
 EQMP
 
diff --git a/qom/cpu.c b/qom/cpu.c
index bb7a618..bc27381 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -25,6 +25,7 @@
 #include "qemu/log.h"
 #include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
+#include "trace/control.h"
 
 bool cpu_exists(int64_t id)
 {
@@ -227,6 +228,17 @@ void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
 void cpu_reset(CPUState *cpu)
 {
     CPUClass *klass = CPU_GET_CLASS(cpu);
+    TraceEvent *ev = NULL;
+
+    if (!qemu_initialized) {
+        /* trace enabled events on all initial vCPUs */
+        while ((ev = trace_event_pattern("*", ev)) != NULL) {
+            if (trace_event_get_cpu_id(ev) != TRACE_CPU_EVENT_COUNT &&
+                trace_event_get_state_dynamic(ev)) {
+                trace_event_set_state_dynamic(ev, true);
+            }
+        }
+    }
 
     if (klass->reset != NULL) {
         (*klass->reset)(cpu);
diff --git a/scripts/tracetool/format/tcg_h.py b/scripts/tracetool/format/tcg_h.py
index 222002c..7a9254f 100644
--- a/scripts/tracetool/format/tcg_h.py
+++ b/scripts/tracetool/format/tcg_h.py
@@ -52,7 +52,11 @@ def generate(events, backend):
 
         if "disable" not in e.properties:
             out('    %(name_trans)s(%(argnames_trans)s);',
-                '    gen_helper_%(name_exec)s(%(argnames_exec)s);',
+                '    if (%(cond)s) {',
+                '        gen_helper_%(name_exec)s(%(argnames_exec)s);',
+                '    }',
+                cond='trace_event_get_cpu_state(_cpu, TRACE_%s_TRANS)' % e.name.upper()
+                     if "vcpu" in e.properties else "true",
                 name_trans=e.event_trans.api(e.QEMU_TRACE),
                 name_exec=e.event_exec.api(e.QEMU_TRACE),
                 argnames_trans=", ".join(e.event_trans.args.names()),
diff --git a/scripts/tracetool/format/tcg_helper_c.py b/scripts/tracetool/format/tcg_helper_c.py
index 96655a0..0cb7f45 100644
--- a/scripts/tracetool/format/tcg_helper_c.py
+++ b/scripts/tracetool/format/tcg_helper_c.py
@@ -6,7 +6,7 @@ Generate trace/generated-helpers.c.
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2015, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -36,8 +36,13 @@ def generate(events, backend):
         # tracetool.generate always transforms types to host
         e_args = e.original.args
 
-        values = ["(%s)%s" % (t, n)
-                  for t, n in e.args.transform(TCG_2_TCG_HELPER_DEF)]
+        values = []
+        for (t_old, n), (t_new, _) in zip(
+                e.args, e.args.transform(TCG_2_TCG_HELPER_DEF)):
+            if t_old == "CPUState *":
+                values.append("ENV_GET_CPU((CPUArchState*)%s)" % n)
+            else:
+                values.append("(%s)%s" % (t_new, n))
 
         out('void %(name_tcg)s(%(args)s)',
             '{',
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index 32f7a32..15896de 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -144,4 +144,6 @@ util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o generated-tracers.o
 util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
 util-obj-$(CONFIG_TRACE_UST) += generated-ust.o
 util-obj-y += control.o
+target-obj-y += control-target.o
+stub-obj-y += control-stub.o
 util-obj-y += qmp.o
diff --git a/trace/control-internal.h b/trace/control-internal.h
index 70e55df..b4069e3 100644
--- a/trace/control-internal.h
+++ b/trace/control-internal.h
@@ -12,6 +12,12 @@
 
 #include <string.h>
 
+#include "qemu-common.h"
+/* GTK headers conflict with QOM's '_' */
+#if !defined(TRACE_CPU_INCLUDE_HACK)
+#include "qom/cpu.h"
+#endif
+
 
 extern TraceEvent trace_events[];
 
@@ -63,11 +69,16 @@ static inline bool trace_event_get_state_dynamic(TraceEvent *ev)
     return ev->dstate;
 }
 
-static inline void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
+static inline bool trace_event_get_cpu_state_dynamic(CPUState *cpu,
+                                                     TraceEvent *ev)
 {
+#if !defined(TRACE_CPU_INCLUDE_HACK)
+    assert(cpu != NULL);
     assert(ev != NULL);
-    assert(trace_event_get_state_static(ev));
-    ev->dstate = state;
+    return cpu->tb_phys_idx & (((unsigned long)1) << ev->cpu_id);
+#else
+    abort();
+#endif
 }
 
 #endif  /* TRACE__CONTROL_INTERNAL_H */
diff --git a/trace/control-stub.c b/trace/control-stub.c
new file mode 100644
index 0000000..dd62d3b
--- /dev/null
+++ b/trace/control-stub.c
@@ -0,0 +1,29 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2014-2015 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "trace/control.h"
+
+
+void trace_init_vcpu_tb_caches(void)
+{
+}
+
+void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
+{
+    assert(ev != NULL);
+    assert(trace_event_get_state_static(ev));
+    ev->dstate = state;
+}
+
+void trace_event_set_cpu_state_dynamic(CPUState *cpu,
+                                       TraceEvent *ev, bool state)
+{
+    /* should never be called on non-target binaries */
+    abort();
+}
diff --git a/trace/control-target.c b/trace/control-target.c
new file mode 100644
index 0000000..84d3243
--- /dev/null
+++ b/trace/control-target.c
@@ -0,0 +1,53 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2014-2015 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "trace/control.h"
+#include "cpu.h"
+#include "translate-all.h"
+
+
+void trace_init_vcpu_tb_caches(void)
+{
+    unsigned int events = 1;
+    TraceEvent *ev = NULL;
+    while ((ev = trace_event_pattern("*", ev)) != NULL) {
+        if (trace_event_get_cpu_id(ev) == TRACE_CPU_EVENT_COUNT) {
+            continue;
+        }
+        events <<= 1;
+    }
+    tb_caches_set(events);
+    tb_caches_apply();
+}
+
+void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
+{
+    CPUState *cpu;
+    assert(ev != NULL);
+    assert(trace_event_get_state_static(ev));
+    CPU_FOREACH(cpu) {
+        trace_event_set_cpu_state_dynamic(cpu, ev, state);
+    }
+    ev->dstate = state;
+}
+
+void trace_event_set_cpu_state_dynamic(CPUState *cpu,
+                                       TraceEvent *ev, bool state)
+{
+    unsigned int bit;
+    assert(cpu != NULL);
+    assert(ev != NULL);
+    assert(trace_event_get_state_static(ev));
+    assert(trace_event_get_cpu_id(ev) != TRACE_CPU_EVENT_COUNT);
+    if (state) {
+        ev->dstate = state;
+    }
+    bit = ((unsigned long)1) << ev->cpu_id;
+    cpu_tb_cache_set(cpu, (cpu_tb_cache_get(cpu) & ~bit) | bit);
+}
diff --git a/trace/control.h b/trace/control.h
index c0680c7..be3864a 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -13,7 +13,8 @@
 #include "qemu-common.h"
 #include "trace/generated-events.h"
 
-
+/* Forward declaration */
+struct CPUState;
 typedef struct CPUState CPUState;
 
 
@@ -117,6 +118,22 @@ static const char * trace_event_get_name(TraceEvent *ev);
     ((id ##_ENABLED) && trace_event_get_state_dynamic(trace_event_id(id)))
 
 /**
+ * trace_event_get_cpu_state:
+ * @id: Event identifier.
+ *
+ * Get the tracing state of an event (both static and dynamic) for the given
+ * vCPU.
+ *
+ * If the event has the disabled property, the check will have no performance
+ * impact.
+ *
+ * As a down side, you must always use an immediate #TraceEventID value.
+ */
+#define trace_event_get_cpu_state(cpu, id)                              \
+    ((id ##_ENABLED) && trace_event_get_cpu_state_dynamic(cpu,          \
+                                                          trace_event_id(id)))
+
+/**
  * trace_event_get_state_static:
  * @id: Event identifier.
  *
@@ -135,6 +152,13 @@ static bool trace_event_get_state_static(TraceEvent *ev);
 static bool trace_event_get_state_dynamic(TraceEvent *ev);
 
 /**
+ * trace_event_get_cpu_state_dynamic:
+ *
+ * Get the dynamic tracing state of an event for the given vCPU.
+ */
+static bool trace_event_get_cpu_state_dynamic(CPUState *cpu, TraceEvent *ev);
+
+/**
  * trace_event_set_state:
  *
  * Set the tracing state of an event (only if possible).
@@ -148,13 +172,36 @@ static bool trace_event_get_state_dynamic(TraceEvent *ev);
     } while (0)
 
 /**
+ * trace_event_set_cpu_state:
+ *
+ * Set the tracing state of an event for the given vCPU (only if possible).
+ */
+#define trace_event_set_cpu_state(cpu, id, state)               \
+    do {                                                        \
+        if ((id ##_ENABLED)) {                                  \
+            TraceEvent *_e = trace_event_id(id);                \
+            trace_event_set_cpu_state_dynamic(cpu, _e, state);  \
+        }                                                       \
+    } while (0)
+
+/**
  * trace_event_set_state_dynamic:
  *
  * Set the dynamic tracing state of an event.
  *
  * Pre-condition: trace_event_get_state_static(ev) == true
  */
-static void trace_event_set_state_dynamic(TraceEvent *ev, bool state);
+void trace_event_set_state_dynamic(TraceEvent *ev, bool state);
+
+/**
+ * trace_event_set_cpu_state_dynamic:
+ *
+ * Set the dynamic tracing state of an event for the given vCPU.
+ *
+ * Pre-condition: trace_event_get_cpu_state_static(ev) == true
+ */
+void trace_event_set_cpu_state_dynamic(CPUState *cpu,
+                                       TraceEvent *ev, bool state);
 
 
 
@@ -171,6 +218,8 @@ static void trace_event_set_state_dynamic(TraceEvent *ev, bool state);
  */
 bool trace_init_backends(const char *events, const char *file);
 
+void trace_init_vcpu_tb_caches(void);
+
 
 #include "trace/control-internal.h"
 
diff --git a/trace/qmp.c b/trace/qmp.c
index a669698..9515a91 100644
--- a/trace/qmp.c
+++ b/trace/qmp.c
@@ -1,7 +1,7 @@
 /*
  * QMP commands for tracing events.
  *
- * Copyright (C) 2014 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2014-2015 Lluís Vilanova <vilanova@ac.upc.edu>
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -44,34 +44,141 @@ TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp)
     return events;
 }
 
+
+static void check_events_are_dynamic(const char *name, bool per_cpu,
+                                     bool *found, bool error_check,
+                                     bool *error_found, Error **errp)
+{
+    TraceEvent *ev = NULL;
+    *found = false;
+    *error_found = false;
+    while ((ev = trace_event_pattern(name, ev)) != NULL) {
+        if (per_cpu && trace_event_get_cpu_id(ev) == TRACE_CPU_EVENT_COUNT) {
+            continue;
+        }
+        *found = true;
+        if (!trace_event_get_state_static(ev)) {
+            if (error_check) {
+                error_setg(
+                    errp, "cannot set dynamic tracing state for \"%s\"\n",
+                    trace_event_get_name(ev));
+                *error_found = true;
+                return;
+            }
+        }
+    }
+}
+
 void qmp_trace_event_set_state(const char *name, bool enable,
                                bool has_ignore_unavailable,
                                bool ignore_unavailable, Error **errp)
 {
+    bool error, found;
+    TraceEvent *ev = NULL;
+
+    /* Check all selected events are dynamic */
+    check_events_are_dynamic(name, false, &found,
+                             !(has_ignore_unavailable && ignore_unavailable),
+                             &error, errp);
+    if (error) {
+        return;
+    }
+    if (!found && !trace_event_is_pattern(name)) {
+        error_setg(errp, "unknown event \"%s\"\n", name);
+        return;
+    }
+
+    /* Apply changes */
+    ev = NULL;
+    while ((ev = trace_event_pattern(name, ev)) != NULL) {
+        if (trace_event_get_state_static(ev)) {
+            trace_event_set_state_dynamic(ev, enable);
+        }
+    }
+}
+
+
+static CPUState *get_cpu_state(int index, Error **errp)
+{
+    CPUState *cpu = qemu_get_cpu(index);
+    if (cpu == NULL) {
+        error_setg(errp, "invalid vCPU index %u\n", index);
+    }
+    return cpu;
+}
+
+TraceEventInfoList *qmp_trace_event_get_cpu_state(const char *name,
+                                                  int64_t vcpu, Error **errp)
+{
+    TraceEventInfoList *events = NULL;
     bool found = false;
     TraceEvent *ev;
+    CPUState *cpu = get_cpu_state(vcpu, errp);
+    if (!cpu) {
+        return NULL;
+    }
 
-    /* Check all selected events are dynamic */
     ev = NULL;
     while ((ev = trace_event_pattern(name, ev)) != NULL) {
-        found = true;
-        if (!(has_ignore_unavailable && ignore_unavailable) &&
-            !trace_event_get_state_static(ev)) {
-            error_setg(errp, "cannot set dynamic tracing state for \"%s\"",
-                       trace_event_get_name(ev));
-            return;
+        TraceEventInfoList *elem;
+        if (trace_event_get_cpu_id(ev) == TRACE_CPU_EVENT_COUNT) {
+            continue;
         }
+        elem = g_new(TraceEventInfoList, 1);
+        elem->value = g_new(TraceEventInfo, 1);
+        elem->value->vcpu =
+            trace_event_get_cpu_id(ev) == TRACE_CPU_EVENT_COUNT ? false : true;
+        elem->value->name = g_strdup(trace_event_get_name(ev));
+        if (!trace_event_get_state_static(ev)) {
+            elem->value->state = TRACE_EVENT_STATE_UNAVAILABLE;
+        } else if (!trace_event_get_state_dynamic(ev)) {
+            elem->value->state = TRACE_EVENT_STATE_DISABLED;
+        } else {
+            elem->value->state = TRACE_EVENT_STATE_ENABLED;
+        }
+        elem->next = events;
+        events = elem;
+        found = true;
     }
+
     if (!found && !trace_event_is_pattern(name)) {
-        error_setg(errp, "unknown event \"%s\"", name);
+        error_setg(errp, "unknown or non-vCPU event \"%s\"\n", name);
+    }
+
+    return events;
+}
+
+void qmp_trace_event_set_cpu_state(const char *name, int64_t vcpu, bool enable,
+                                   bool has_ignore_unavailable,
+                                   bool ignore_unavailable, Error **errp)
+{
+    bool error, found;
+    TraceEvent *ev = NULL;
+    CPUState *cpu = get_cpu_state(vcpu, errp);
+    if (!cpu) {
+        return;
+    }
+
+    /* Check all selected events are dynamic */
+    check_events_are_dynamic(name, true, &found,
+                             !(has_ignore_unavailable && ignore_unavailable),
+                             &error, errp);
+    if (error) {
+        return;
+    }
+    if (!found && !trace_event_is_pattern(name)) {
+        error_setg(errp, "unknown or non-vCPU event \"%s\"\n", name);
         return;
     }
 
     /* Apply changes */
     ev = NULL;
     while ((ev = trace_event_pattern(name, ev)) != NULL) {
+        if (trace_event_get_cpu_id(ev) == TRACE_CPU_EVENT_COUNT) {
+            continue;
+        }
         if (trace_event_get_state_static(ev)) {
-            trace_event_set_state_dynamic(ev, enable);
+            trace_event_set_cpu_state_dynamic(cpu, ev, enable);
         }
     }
 }
diff --git a/translate-all.c b/translate-all.c
index 5ae64d6..4e4c8e2 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -179,6 +179,7 @@ void cpu_gen_init(void)
     tcg_ctx.tb_ctx.tb_phys_hash_size_req = 1;
     tcg_ctx.tb_ctx.tb_phys_hash = NULL;
     tb_caches_apply();
+    trace_init_vcpu_tb_caches();
 }
 
 /* Encode VAL as a signed leb128 sequence at P.
diff --git a/ui/Makefile.objs b/ui/Makefile.objs
index 0034fbb..453b482 100644
--- a/ui/Makefile.objs
+++ b/ui/Makefile.objs
@@ -34,7 +34,7 @@ common-obj-y += egl-helpers.o
 common-obj-$(CONFIG_GTK) += gtk-egl.o
 endif
 
-gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS)
+gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) -DTRACE_CPU_INCLUDE_HACK
 gtk-egl.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) $(OPENGL_CFLAGS)
 shader.o-cflags += $(OPENGL_CFLAGS)
 console-gl.o-cflags += $(OPENGL_CFLAGS)

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states
  2015-10-13 17:10 [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
                   ` (7 preceding siblings ...)
  2015-10-13 17:11 ` [Qemu-devel] [PATCHv18/8] trace: [tcg] Add per-vCPU tracing states for events with the 'vcpu' property Lluís Vilanova
@ 2015-10-13 17:26 ` Lluís Vilanova
  8 siblings, 0 replies; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 17:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stefan Hajnoczi

Sorry I messed the title format, but I guess this does not warrant a re-send.

Cheers,
  Lluis

-- 
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv13/8] trace: [tcg] Identify events with the 'vcpu' property
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv13/8] trace: [tcg] Identify events with the 'vcpu' property Lluís Vilanova
@ 2015-10-13 17:33   ` Eric Blake
  2015-10-13 18:27     ` Lluís Vilanova
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Blake @ 2015-10-13 17:33 UTC (permalink / raw)
  To: Lluís Vilanova, qemu-devel
  Cc: Stefan Hajnoczi, Markus Armbruster, Stefan Hajnoczi

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

On 10/13/2015 11:10 AM, Lluís Vilanova wrote:
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>

If you'd send with 'qemu format-patch/send-email -v1', then your subject
line would be formatted [PATCH v1 3/8] instead of the confusing results
you got by omitting spaces [PATCHv13/8] (this is v13? out of 8?).  Also,
no need to include v1 (it's fairly obvious that an unversioned patch is
the first), you really only need the designation for -v2 and beyond.

The one-line commit subject correctly explains the 'what', but there is
no commit body explaining the 'why'.  While a commit body is not
mandatory, it usually helps.

> +++ b/qapi/trace.json
> @@ -1,6 +1,6 @@
>  # -*- mode: python -*-
>  #
> -# Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
> +# Copyright (C) 2011-2015 Lluís Vilanova <vilanova@ac.upc.edu>
>  #
>  # This work is licensed under the terms of the GNU GPL, version 2 or later.
>  # See the COPYING file in the top-level directory.
> @@ -29,11 +29,12 @@
>  #
>  # @name: Event name.
>  # @state: Tracing state.
> +# @vcpu: Whether this is a per-vCPU event.
>  #

Missing a '(since 2.5)' comment on the @vcpu line.

>  # Since 2.2
>  ##
>  { 'struct': 'TraceEventInfo',
> -  'data': {'name': 'str', 'state': 'TraceEventState'} }
> +  'data': {'name': 'str', 'state': 'TraceEventState', 'vcpu': 'bool'} }

This is okay from the qapi interface perspective (events are output, so
unconditional addition of new fields won't break existing clients).

I did not closely review the rest, however, I did spot this:

> +++ b/trace/qmp.c
> @@ -22,6 +22,8 @@ TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp)
>      while ((ev = trace_event_pattern(name, ev)) != NULL) {
>          TraceEventInfoList *elem = g_new(TraceEventInfoList, 1);
>          elem->value = g_new(TraceEventInfo, 1);
> +        elem->value->vcpu =
> +            trace_event_get_cpu_id(ev) == TRACE_CPU_EVENT_COUNT ? false : true;

I'm not a fan of the over-verbose 'cond ? false : true'.  It can almost
always be written '!cond' with just as much clarity.  In your case:

elem->value->vcpu = trace_event_get_cpu_id(ev) != TRACE_CPU_EVENT_COUNT;

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv18/8] trace: [tcg] Add per-vCPU tracing states for events with the 'vcpu' property
  2015-10-13 17:11 ` [Qemu-devel] [PATCHv18/8] trace: [tcg] Add per-vCPU tracing states for events with the 'vcpu' property Lluís Vilanova
@ 2015-10-13 17:50   ` Eric Blake
  2015-10-13 19:43     ` Lluís Vilanova
  2015-10-16  9:19   ` Stefan Hajnoczi
  1 sibling, 1 reply; 23+ messages in thread
From: Eric Blake @ 2015-10-13 17:50 UTC (permalink / raw)
  To: Lluís Vilanova, qemu-devel
  Cc: Stefan Hajnoczi, Gerd Hoffmann, Andreas Färber,
	Stefan Hajnoczi, Markus Armbruster

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

On 10/13/2015 11:11 AM, Lluís Vilanova wrote:
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---

Interface review only.

> +++ b/qapi/trace.json
> @@ -64,3 +64,34 @@
>  ##
>  { 'command': 'trace-event-set-state',
>    'data': {'name': 'str', 'enable': 'bool', '*ignore-unavailable': 'bool'} }
> +
> +##
> +# @trace-event-get-cpu-state:
> +#
> +# Query the state of events in a given vCPU.
> +#
> +# @name: Event name pattern.
> +# @vcpu: The vCPU to check.
> +#
> +# Returns: @TraceEventInfo of the matched events
> +#
> +# Since 2.2

2.5, not 2.2

> +##
> +{ 'command': 'trace-event-get-cpu-state',
> +  'data': {'name': 'str', 'vcpu': 'int'},
> +  'returns': ['TraceEventInfo'] }
> +
> +##
> +# @trace-event-set-cpu-state:
> +#
> +# Set the dynamic state of events in a given vCPU.
> +#
> +# @name: Event name pattern.
> +# @vcpu: The vCPU to act upon.
> +# @enable: Whether to enable tracing.
> +# @ignore-unavailable: #optional Do not match unavailable events with @name.
> +#
> +# Since 2.2

2.5, not 2.2

> +##
> +{ 'command': 'trace-event-set-cpu-state',
> +  'data': {'name': 'str', 'vcpu': 'int', 'enable': 'bool', '*ignore-unavailable': 'bool'} }

This looks identical to trace-event-set-state, except that it now has a
'vcpu':'int' argument.  Would it be any simpler to just modify the
existing command:

##
# @trace-event-set-state:
...
# @vcpu: #optional If provided, limit the state change to the given vcpu
(default act on all vcpus) (since 2.5)
#
# Since 2.2
##
 { 'command': 'trace-event-set-state',
   'data': {'name': 'str', 'enable': 'bool',
            '*vcpu': 'int', '*ignore-unavailable': 'bool'} }

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv13/8] trace: [tcg] Identify events with the 'vcpu' property
  2015-10-13 17:33   ` Eric Blake
@ 2015-10-13 18:27     ` Lluís Vilanova
  2015-10-13 18:57       ` Markus Armbruster
  0 siblings, 1 reply; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 18:27 UTC (permalink / raw)
  To: Eric Blake
  Cc: Stefan Hajnoczi, qemu-devel, Stefan Hajnoczi, Markus Armbruster

Eric Blake writes:

> On 10/13/2015 11:10 AM, Lluís Vilanova wrote:
>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>

> If you'd send with 'qemu format-patch/send-email -v1', then your subject
> line would be formatted [PATCH v1 3/8] instead of the confusing results
> you got by omitting spaces [PATCHv13/8] (this is v13? out of 8?).  Also,
> no need to include v1 (it's fairly obvious that an unversioned patch is
> the first), you really only need the designation for -v2 and beyond.

Right, it's just that "stgit mail" does not add the spaces for you.


> The one-line commit subject correctly explains the 'what', but there is
> no commit body explaining the 'why'.  While a commit body is not
> mandatory, it usually helps.

I've had these lying around for a very long time and now I see I got lazy in
writing the descriptions. Sorry about that.


>> +++ b/qapi/trace.json
>> @@ -1,6 +1,6 @@
>> # -*- mode: python -*-
>> #
>> -# Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
>> +# Copyright (C) 2011-2015 Lluís Vilanova <vilanova@ac.upc.edu>
>> #
>> # This work is licensed under the terms of the GNU GPL, version 2 or later.
>> # See the COPYING file in the top-level directory.
>> @@ -29,11 +29,12 @@
>> #
>> # @name: Event name.
>> # @state: Tracing state.
>> +# @vcpu: Whether this is a per-vCPU event.
>> #

> Missing a '(since 2.5)' comment on the @vcpu line.

[...]
>> +++ b/trace/qmp.c
>> @@ -22,6 +22,8 @@ TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp)
>> while ((ev = trace_event_pattern(name, ev)) != NULL) {
>> TraceEventInfoList *elem = g_new(TraceEventInfoList, 1);
elem-> value = g_new(TraceEventInfo, 1);
>> +        elem->value->vcpu =
>> +            trace_event_get_cpu_id(ev) == TRACE_CPU_EVENT_COUNT ? false : true;

> I'm not a fan of the over-verbose 'cond ? false : true'.  It can almost
> always be written '!cond' with just as much clarity.  In your case:

> elem-> value->vcpu = trace_event_get_cpu_id(ev) != TRACE_CPU_EVENT_COUNT;

I guess it's a matter of personal taste. I'll add both to version 2.


Thanks,
  Lluis

-- 
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv17/8] [trivial] Track when QEMU has finished initialization
  2015-10-13 17:11 ` [Qemu-devel] [PATCHv17/8] [trivial] Track when QEMU has finished initialization Lluís Vilanova
@ 2015-10-13 18:56   ` Markus Armbruster
  0 siblings, 0 replies; 23+ messages in thread
From: Markus Armbruster @ 2015-10-13 18:56 UTC (permalink / raw)
  To: Lluís Vilanova
  Cc: Blue Swirl, Stefan Hajnoczi, Riku Voipio, qemu-devel,
	Paolo Bonzini

Lluís Vilanova <vilanova@ac.upc.edu> writes:

> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>

Drive-by shooting: the commit message should explain *why* you need to
track this.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv13/8] trace: [tcg] Identify events with the 'vcpu' property
  2015-10-13 18:27     ` Lluís Vilanova
@ 2015-10-13 18:57       ` Markus Armbruster
  0 siblings, 0 replies; 23+ messages in thread
From: Markus Armbruster @ 2015-10-13 18:57 UTC (permalink / raw)
  To: Lluís Vilanova; +Cc: Stefan Hajnoczi, qemu-devel, Stefan Hajnoczi

Lluís Vilanova <vilanova@ac.upc.edu> writes:

> Eric Blake writes:
>
>> On 10/13/2015 11:10 AM, Lluís Vilanova wrote:
>>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
>
>> If you'd send with 'qemu format-patch/send-email -v1', then your subject
>> line would be formatted [PATCH v1 3/8] instead of the confusing results
>> you got by omitting spaces [PATCHv13/8] (this is v13? out of 8?).  Also,
>> no need to include v1 (it's fairly obvious that an unversioned patch is
>> the first), you really only need the designation for -v2 and beyond.
>
> Right, it's just that "stgit mail" does not add the spaces for you.

Then you get to add them yourself, or you get to switch to a tool that
does :)

[...]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv18/8] trace: [tcg] Add per-vCPU tracing states for events with the 'vcpu' property
  2015-10-13 17:50   ` Eric Blake
@ 2015-10-13 19:43     ` Lluís Vilanova
  0 siblings, 0 replies; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-13 19:43 UTC (permalink / raw)
  To: Eric Blake
  Cc: Stefan Hajnoczi, Markus Armbruster, qemu-devel, Gerd Hoffmann,
	Stefan Hajnoczi, Andreas Färber

Eric Blake writes:

> On 10/13/2015 11:11 AM, Lluís Vilanova wrote:
[...]
>> +##
>> +{ 'command': 'trace-event-get-cpu-state',
>> +  'data': {'name': 'str', 'vcpu': 'int'},
>> +  'returns': ['TraceEventInfo'] }
>> +
>> +##
>> +# @trace-event-set-cpu-state:
>> +#
>> +# Set the dynamic state of events in a given vCPU.
>> +#
>> +# @name: Event name pattern.
>> +# @vcpu: The vCPU to act upon.
>> +# @enable: Whether to enable tracing.
>> +# @ignore-unavailable: #optional Do not match unavailable events with @name.
>> +#
>> +# Since 2.2

> 2.5, not 2.2

Old patches :)

>> +##
>> +{ 'command': 'trace-event-set-cpu-state',
>> +  'data': {'name': 'str', 'vcpu': 'int', 'enable': 'bool', '*ignore-unavailable': 'bool'} }

> This looks identical to trace-event-set-state, except that it now has a
> 'vcpu':'int' argument.  Would it be any simpler to just modify the
> existing command:

> ##
> # @trace-event-set-state:
> ...
> # @vcpu: #optional If provided, limit the state change to the given vcpu
> (default act on all vcpus) (since 2.5)
> #
> # Since 2.2
> ##
>  { 'command': 'trace-event-set-state',
>    'data': {'name': 'str', 'enable': 'bool',
>             '*vcpu': 'int', '*ignore-unavailable': 'bool'} }

Hmmm, this certainly minimizes the interface size, but in exchange breaks the
symmetry between trace-event-get-state/trace-event-set-state and
trace-event-get-cpu-state/trace-event-set-cpu-state, and the symmetry between
these commands and the function inside QEMU (this last one probably not very
important).

What I could do is also merge trace-event-get-state and
trace-event-get-cpu-state into a single command with an optional cpu.

This reminds me that the meaning of "get-state" for per-vCPU events is somewhat
tricky in the current implementation. There's a per-event boolean with the
system-wide tracing state, and a per-cpu-and-event boolean for the per-CPU
tracing state. The get/set-event functions let you interact with type of
booleans separately.

If anyone sees it useful, I can make it a bit easier to understand: if no CPU
number is provided, get-state returns true if it's set on any CPU, and set-state
sets the state on all CPUs by default.


Thanks,
  Lluis

-- 
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv11/8] trace: Add support for vCPU pointers in trace events
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv11/8] trace: Add support for vCPU pointers in trace events Lluís Vilanova
@ 2015-10-16  9:13   ` Stefan Hajnoczi
  2015-10-16 15:12     ` Eduardo Habkost
  0 siblings, 1 reply; 23+ messages in thread
From: Stefan Hajnoczi @ 2015-10-16  9:13 UTC (permalink / raw)
  To: Lluís Vilanova
  Cc: Peter Maydell, Guan Xuetao, Eduardo Habkost, Stefan Hajnoczi,
	Anthony Green, Mark Cave-Ayland, qemu-devel, Alexander Graf,
	Jia Liu, Blue Swirl, Max Filippov, Michael Walle,
	open list:PowerPC, Edgar E. Iglesias, Paolo Bonzini,
	Bastian Koppelmann, Leon Alrae, Aurelien Jarno, Richard Henderson

On Tue, Oct 13, 2015 at 07:10:27PM +0200, Lluís Vilanova wrote:
> diff --git a/trace/control.h b/trace/control.h
> index da9bb6b..1a78a7b 100644
> --- a/trace/control.h
> +++ b/trace/control.h
> @@ -1,7 +1,7 @@
>  /*
>   * Interface for configuring and controlling the state of tracing events.
>   *
> - * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
> + * Copyright (C) 2011-2015 Lluís Vilanova <vilanova@ac.upc.edu>
>   *
>   * This work is licensed under the terms of the GNU GPL, version 2 or later.
>   * See the COPYING file in the top-level directory.
> @@ -14,6 +14,9 @@
>  #include "trace/generated-events.h"
>  
>  
> +typedef struct CPUState CPUState;
> +
> +

Wat? :)

Isn't there any other place to put this typedef?

Stefan

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv12/8] trace: Add 'vcpu' event property
  2015-10-13 17:10 ` [Qemu-devel] [PATCHv12/8] trace: Add 'vcpu' event property Lluís Vilanova
@ 2015-10-16  9:16   ` Stefan Hajnoczi
  2015-10-16 15:45     ` Lluís Vilanova
  0 siblings, 1 reply; 23+ messages in thread
From: Stefan Hajnoczi @ 2015-10-16  9:16 UTC (permalink / raw)
  To: Lluís Vilanova; +Cc: Stefan Hajnoczi, qemu-devel

On Tue, Oct 13, 2015 at 07:10:33PM +0200, Lluís Vilanova wrote:
> diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
> index 9b39430..4bdb48f 100644
> --- a/scripts/tracetool/format/h.py
> +++ b/scripts/tracetool/format/h.py
> @@ -6,7 +6,7 @@ trace/generated-tracers.h
>  """
>  
>  __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
> -__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
> +__copyright__  = "Copyright 2012-2015, Lluís Vilanova <vilanova@ac.upc.edu>"
>  __license__    = "GPL version 2 or (at your option) any later version"
>  
>  __maintainer__ = "Stefan Hajnoczi"
> @@ -23,6 +23,8 @@ def generate(events, backend):
>          '#define TRACE__GENERATED_TRACERS_H',
>          '',
>          '#include "qemu-common.h"',
> +        '',
> +        'typedef struct CPUState CPUState;',

Here...

> diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py
> index bc97093..92064f0 100644
> --- a/scripts/tracetool/format/ust_events_c.py
> +++ b/scripts/tracetool/format/ust_events_c.py
> @@ -6,7 +6,7 @@ trace/generated-ust.c
>  """
>  
>  __author__     = "Mohamad Gebai <mohamad.gebai@polymtl.ca>"
> -__copyright__  = "Copyright 2012, Mohamad Gebai <mohamad.gebai@polymtl.ca>"
> +__copyright__  = "Copyright 2012, 2015, Mohamad Gebai <mohamad.gebai@polymtl.ca>"
>  __license__    = "GPL version 2 or (at your option) any later version"
>  
>  __maintainer__ = "Stefan Hajnoczi"
> @@ -30,4 +30,6 @@ def generate(events, backend):
>          ' */',
>          '#pragma GCC diagnostic ignored "-Wredundant-decls"',
>          '',
> +        'typedef struct CPUState CPUState;',
> +        '',
>          '#include "generated-ust-provider.h"')

...and here is okay but please generate a comment so it's clear why this
needs to be defined.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv18/8] trace: [tcg] Add per-vCPU tracing states for events with the 'vcpu' property
  2015-10-13 17:11 ` [Qemu-devel] [PATCHv18/8] trace: [tcg] Add per-vCPU tracing states for events with the 'vcpu' property Lluís Vilanova
  2015-10-13 17:50   ` Eric Blake
@ 2015-10-16  9:19   ` Stefan Hajnoczi
  2015-10-16 15:42     ` Lluís Vilanova
  1 sibling, 1 reply; 23+ messages in thread
From: Stefan Hajnoczi @ 2015-10-16  9:19 UTC (permalink / raw)
  To: Lluís Vilanova
  Cc: Stefan Hajnoczi, qemu-devel, Markus Armbruster, Gerd Hoffmann,
	Andreas Färber

On Tue, Oct 13, 2015 at 07:11:07PM +0200, Lluís Vilanova wrote:
> diff --git a/trace/control-internal.h b/trace/control-internal.h
> index 70e55df..b4069e3 100644
> --- a/trace/control-internal.h
> +++ b/trace/control-internal.h
> @@ -12,6 +12,12 @@
>  
>  #include <string.h>
>  
> +#include "qemu-common.h"
> +/* GTK headers conflict with QOM's '_' */
> +#if !defined(TRACE_CPU_INCLUDE_HACK)
> +#include "qom/cpu.h"
> +#endif
> +
>  
>  extern TraceEvent trace_events[];
>  
> @@ -63,11 +69,16 @@ static inline bool trace_event_get_state_dynamic(TraceEvent *ev)
>      return ev->dstate;
>  }
>  
> -static inline void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
> +static inline bool trace_event_get_cpu_state_dynamic(CPUState *cpu,
> +                                                     TraceEvent *ev)
>  {
> +#if !defined(TRACE_CPU_INCLUDE_HACK)
> +    assert(cpu != NULL);
>      assert(ev != NULL);
> -    assert(trace_event_get_state_static(ev));
> -    ev->dstate = state;
> +    return cpu->tb_phys_idx & (((unsigned long)1) << ev->cpu_id);
> +#else
> +    abort();
> +#endif
>  }

What exactly is the header conflict?

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv11/8] trace: Add support for vCPU pointers in trace events
  2015-10-16  9:13   ` Stefan Hajnoczi
@ 2015-10-16 15:12     ` Eduardo Habkost
  2015-10-16 15:44       ` Lluís Vilanova
  0 siblings, 1 reply; 23+ messages in thread
From: Eduardo Habkost @ 2015-10-16 15:12 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Peter Maydell, Guan Xuetao, Jia Liu, Stefan Hajnoczi,
	Anthony Green, Mark Cave-Ayland, qemu-devel, Alexander Graf,
	Blue Swirl, Max Filippov, Michael Walle, open list:PowerPC,
	Paolo Bonzini, Edgar E. Iglesias, Bastian Koppelmann, Leon Alrae,
	Lluís Vilanova, Aurelien Jarno, Richard Henderson

On Fri, Oct 16, 2015 at 11:13:21AM +0200, Stefan Hajnoczi wrote:
> On Tue, Oct 13, 2015 at 07:10:27PM +0200, Lluís Vilanova wrote:
> > diff --git a/trace/control.h b/trace/control.h
> > index da9bb6b..1a78a7b 100644
> > --- a/trace/control.h
> > +++ b/trace/control.h
> > @@ -1,7 +1,7 @@
> >  /*
> >   * Interface for configuring and controlling the state of tracing events.
> >   *
> > - * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
> > + * Copyright (C) 2011-2015 Lluís Vilanova <vilanova@ac.upc.edu>
> >   *
> >   * This work is licensed under the terms of the GNU GPL, version 2 or later.
> >   * See the COPYING file in the top-level directory.
> > @@ -14,6 +14,9 @@
> >  #include "trace/generated-events.h"
> >  
> >  
> > +typedef struct CPUState CPUState;
> > +
> > +
> 
> Wat? :)
> 
> Isn't there any other place to put this typedef?

I believe you mean include/qemu/typedefs.h. :)

-- 
Eduardo

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv18/8] trace: [tcg] Add per-vCPU tracing states for events with the 'vcpu' property
  2015-10-16  9:19   ` Stefan Hajnoczi
@ 2015-10-16 15:42     ` Lluís Vilanova
  0 siblings, 0 replies; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-16 15:42 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Stefan Hajnoczi, qemu-devel, Markus Armbruster, Gerd Hoffmann,
	Andreas Färber

Stefan Hajnoczi writes:

> On Tue, Oct 13, 2015 at 07:11:07PM +0200, Lluís Vilanova wrote:
>> diff --git a/trace/control-internal.h b/trace/control-internal.h
>> index 70e55df..b4069e3 100644
>> --- a/trace/control-internal.h
>> +++ b/trace/control-internal.h
>> @@ -12,6 +12,12 @@
>> 
>> #include <string.h>
>> 
>> +#include "qemu-common.h"
>> +/* GTK headers conflict with QOM's '_' */
>> +#if !defined(TRACE_CPU_INCLUDE_HACK)
>> +#include "qom/cpu.h"
>> +#endif
>> +
>> 
>> extern TraceEvent trace_events[];
>> 
>> @@ -63,11 +69,16 @@ static inline bool trace_event_get_state_dynamic(TraceEvent *ev)
>> return ev->dstate;
>> }
>> 
>> -static inline void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
>> +static inline bool trace_event_get_cpu_state_dynamic(CPUState *cpu,
>> +                                                     TraceEvent *ev)
>> {
>> +#if !defined(TRACE_CPU_INCLUDE_HACK)
>> +    assert(cpu != NULL);
>> assert(ev != NULL);
>> -    assert(trace_event_get_state_static(ev));
>> -    ev->dstate = state;
>> +    return cpu->tb_phys_idx & (((unsigned long)1) << ev->cpu_id);
>> +#else
>> +    abort();
>> +#endif
>> }

> What exactly is the header conflict?

To be honest, I will try recompiling without that specific patch for the next
version (and document why is that necessary), since I had them lying around for
a long time and only checked if they compiled and run as supposed.


Thanks,
  Lluis

-- 
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv11/8] trace: Add support for vCPU pointers in trace events
  2015-10-16 15:12     ` Eduardo Habkost
@ 2015-10-16 15:44       ` Lluís Vilanova
  0 siblings, 0 replies; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-16 15:44 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Peter Maydell, Guan Xuetao, Jia Liu, Stefan Hajnoczi,
	Anthony Green, Mark Cave-Ayland, qemu-devel, Alexander Graf,
	Blue Swirl, Max Filippov, Michael Walle, open list:PowerPC,
	Stefan Hajnoczi, Paolo Bonzini, Edgar E. Iglesias,
	Bastian Koppelmann, Leon Alrae, Aurelien Jarno, Richard Henderson

Eduardo Habkost writes:

> On Fri, Oct 16, 2015 at 11:13:21AM +0200, Stefan Hajnoczi wrote:
>> On Tue, Oct 13, 2015 at 07:10:27PM +0200, Lluís Vilanova wrote:
>> > diff --git a/trace/control.h b/trace/control.h
>> > index da9bb6b..1a78a7b 100644
>> > --- a/trace/control.h
>> > +++ b/trace/control.h
>> > @@ -1,7 +1,7 @@
>> >  /*
>> >   * Interface for configuring and controlling the state of tracing events.
>> >   *
>> > - * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
>> > + * Copyright (C) 2011-2015 Lluís Vilanova <vilanova@ac.upc.edu>
>> >   *
>> >   * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> >   * See the COPYING file in the top-level directory.
>> > @@ -14,6 +14,9 @@
>> >  #include "trace/generated-events.h"
>> >  
>> >  
>> > +typedef struct CPUState CPUState;
>> > +
>> > +
>> 
>> Wat? :)
>> 
>> Isn't there any other place to put this typedef?

> I believe you mean include/qemu/typedefs.h. :)

Oh! That's exactly what I needed :)


Thanks,
  Lluis

-- 
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCHv12/8] trace: Add 'vcpu' event property
  2015-10-16  9:16   ` Stefan Hajnoczi
@ 2015-10-16 15:45     ` Lluís Vilanova
  0 siblings, 0 replies; 23+ messages in thread
From: Lluís Vilanova @ 2015-10-16 15:45 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: Stefan Hajnoczi, qemu-devel

Stefan Hajnoczi writes:

> On Tue, Oct 13, 2015 at 07:10:33PM +0200, Lluís Vilanova wrote:
>> diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
>> index 9b39430..4bdb48f 100644
>> --- a/scripts/tracetool/format/h.py
>> +++ b/scripts/tracetool/format/h.py
>> @@ -6,7 +6,7 @@ trace/generated-tracers.h
>> """
>> 
>> __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
>> -__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
>> +__copyright__  = "Copyright 2012-2015, Lluís Vilanova <vilanova@ac.upc.edu>"
>> __license__    = "GPL version 2 or (at your option) any later version"
>> 
>> __maintainer__ = "Stefan Hajnoczi"
>> @@ -23,6 +23,8 @@ def generate(events, backend):
>> '#define TRACE__GENERATED_TRACERS_H',
>> '',
>> '#include "qemu-common.h"',
>> +        '',
>> +        'typedef struct CPUState CPUState;',

> Here...

>> diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py
>> index bc97093..92064f0 100644
>> --- a/scripts/tracetool/format/ust_events_c.py
>> +++ b/scripts/tracetool/format/ust_events_c.py
>> @@ -6,7 +6,7 @@ trace/generated-ust.c
>> """
>> 
>> __author__     = "Mohamad Gebai <mohamad.gebai@polymtl.ca>"
>> -__copyright__  = "Copyright 2012, Mohamad Gebai <mohamad.gebai@polymtl.ca>"
>> +__copyright__  = "Copyright 2012, 2015, Mohamad Gebai <mohamad.gebai@polymtl.ca>"
>> __license__    = "GPL version 2 or (at your option) any later version"
>> 
>> __maintainer__ = "Stefan Hajnoczi"
>> @@ -30,4 +30,6 @@ def generate(events, backend):
>> ' */',
>> '#pragma GCC diagnostic ignored "-Wredundant-decls"',
>> '',
>> +        'typedef struct CPUState CPUState;',
>> +        '',
>> '#include "generated-ust-provider.h"')

> ...and here is okay but please generate a comment so it's clear why this
> needs to be defined.

Will do.

Thanks,
  Lluis

-- 
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2015-10-16 15:45 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-13 17:10 [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova
2015-10-13 17:10 ` [Qemu-devel] [PATCHv11/8] trace: Add support for vCPU pointers in trace events Lluís Vilanova
2015-10-16  9:13   ` Stefan Hajnoczi
2015-10-16 15:12     ` Eduardo Habkost
2015-10-16 15:44       ` Lluís Vilanova
2015-10-13 17:10 ` [Qemu-devel] [PATCHv12/8] trace: Add 'vcpu' event property Lluís Vilanova
2015-10-16  9:16   ` Stefan Hajnoczi
2015-10-16 15:45     ` Lluís Vilanova
2015-10-13 17:10 ` [Qemu-devel] [PATCHv13/8] trace: [tcg] Identify events with the 'vcpu' property Lluís Vilanova
2015-10-13 17:33   ` Eric Blake
2015-10-13 18:27     ` Lluís Vilanova
2015-10-13 18:57       ` Markus Armbruster
2015-10-13 17:10 ` [Qemu-devel] [PATCHv14/8] exec: [tcg] Refactor flush of per-CPU virtual TB cache Lluís Vilanova
2015-10-13 17:10 ` [Qemu-devel] [PATCHv15/8] exec: [ŧcg] Use multiple physical TB caches Lluís Vilanova
2015-10-13 17:10 ` [Qemu-devel] [PATCHv16/8] exec: [tcg] Track which vCPU is performing translation and execution Lluís Vilanova
2015-10-13 17:11 ` [Qemu-devel] [PATCHv17/8] [trivial] Track when QEMU has finished initialization Lluís Vilanova
2015-10-13 18:56   ` Markus Armbruster
2015-10-13 17:11 ` [Qemu-devel] [PATCHv18/8] trace: [tcg] Add per-vCPU tracing states for events with the 'vcpu' property Lluís Vilanova
2015-10-13 17:50   ` Eric Blake
2015-10-13 19:43     ` Lluís Vilanova
2015-10-16  9:19   ` Stefan Hajnoczi
2015-10-16 15:42     ` Lluís Vilanova
2015-10-13 17:26 ` [Qemu-devel] [RFC][PATCHv10/8] trace: Per-vCPU tracing states Lluís Vilanova

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).