All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v6 0/7] trace: Per-vCPU tracing states
@ 2016-06-23 15:21 Lluís Vilanova
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 1/7] trace: Identify events with the 'vcpu' property Lluís Vilanova
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Lluís Vilanova @ 2016-06-23 15:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Eric Blake, Eduardo Habkost, Stefan Hajnoczi

NOTE: This series applies on top of "trace: [*-user] Add commandline arguments
      to control tracing".

Provides per-vCPU dynamic controls of the tracing state of events with the
"vcpu" property.

A later series proposes an optimization where tracing code can be elided for
dynamically disabled events (it uses multiple virtual TB caches optimized for
the current tracing state of the executing vCPU).


Changes in v6
=============

* Rebase on 6f1d2d1.
* Add missing include in "scripts/tracetool/format/h.py".


Changes in v5
=============

* Fix 'trace_event_is_vcpu()'.
* Move stub code into the "stubs/" directory [Stefan Hajnoczi].
* Improve docs on QAPI and QMP commands [Markus Armbruster].
* Rewrite 'get_cpu()' to be more in line with use of QEMU's Error objects
  [Markus Armbruster].
* Add "name" argument to HMP command "info trace-events".
* Add "vcpu" argument to HMP commands [Markus Armbruster].


Changes in v4
=============

* Make trace_events_dstate an uint16_t [Paolo Bonzini].
* Revert trace_event_get_state_dynamic_by_id [Stefan Hajnoczi].
* Do not add superfluous asserts [Paolo Bonzini].
* Replace cpu -> vcpu in function names and arguments [Paolo Bonzini].
* Add 'trace_event_is_vcpu' [Paolo Bonzini].
* Remove 'trace_event_cpu_count' [Paolo Bonzini].


Changes in v3
=============

* Update QAPI version annotations [Eric Blake].


Changes in v2
=============

* Rebase on 9bbbf64.
* Fix removal of macro '_' in all target architectures.
* Document behaviour of 'trace_events_dstate'.
* Use a proper bitmap for CPUState::trace_dstate [Stefan Hajnoczi].


Changes in v1
=============

* Rebase on 1b16240.
* Split from v4 of "trace: Per-vCPU tracing states".
* Simplify event state initialization.
* Simplify logic deciding which events are treated by this patch (previously,
  execution-time events with 'tcg' and 'vcpu' properties; now it's simply events
  with the 'vcpu' property).
* Make tracing backends comply with the per-vCPU tracing state.


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

Lluís Vilanova (7):
      trace: Identify events with the 'vcpu' property
      disas: Remove unused macro '_'
      [trivial] trace: Cosmetic changes on fast-path tracing
      trace: Add per-vCPU tracing states for events with the 'vcpu' property
      trace: Conditionally trace events based on their per-vCPU state
      trace: Allow event name pattern in "info trace-events"
      trace: Add QAPI/QMP interfaces to query and control per-vCPU tracing state


 bsd-user/main.c                      |    1 
 disas/alpha.c                        |    6 +
 disas/arm.c                          |    2 
 disas/i386.c                         |    2 
 disas/m68k.c                         |    4 -
 disas/mips.c                         |   50 ++++++-----
 disas/ppc.c                          |   22 +++--
 disas/sparc.c                        |    6 +
 hmp-commands-info.hx                 |    8 +-
 hmp-commands.hx                      |    7 +-
 hmp.h                                |    1 
 include/disas/bfd.h                  |    1 
 include/qom/cpu.h                    |    6 +
 linux-user/main.c                    |    1 
 monitor.c                            |   46 ++++++++++-
 qapi/trace.json                      |   32 ++++++-
 qmp-commands.hx                      |   35 ++++++++
 qom/cpu.c                            |    1 
 scripts/tracetool/backend/dtrace.py  |    4 -
 scripts/tracetool/backend/ftrace.py  |   20 ++---
 scripts/tracetool/backend/log.py     |   26 ++++--
 scripts/tracetool/backend/simple.py  |   13 ++-
 scripts/tracetool/backend/ust.py     |    4 -
 scripts/tracetool/format/events_c.py |   11 ++-
 scripts/tracetool/format/events_h.py |   12 +++
 scripts/tracetool/format/h.py        |   19 ++++
 stubs/Makefile.objs                  |    1 
 stubs/trace-control.c                |   28 ++++++
 trace/Makefile.objs                  |    4 +
 trace/control-internal.h             |   47 +++++++++--
 trace/control-target.c               |   53 ++++++++++++
 trace/control.c                      |   29 ++++++-
 trace/control.h                      |   78 ++++++++++++++++++
 trace/event-internal.h               |    4 +
 trace/qmp.c                          |  148 +++++++++++++++++++++++++++-------
 translate-all.h                      |    3 +
 vl.c                                 |    1 
 37 files changed, 600 insertions(+), 136 deletions(-)
 create mode 100644 stubs/trace-control.c
 create mode 100644 trace/control-target.c


To: qemu-devel@nongnu.org
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Eric Blake <eblake@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>

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

* [Qemu-devel] [PATCH v6 1/7] trace: Identify events with the 'vcpu' property
  2016-06-23 15:21 [Qemu-devel] [PATCH v6 0/7] trace: Per-vCPU tracing states Lluís Vilanova
@ 2016-06-23 15:21 ` Lluís Vilanova
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 2/7] disas: Remove unused macro '_' Lluís Vilanova
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Lluís Vilanova @ 2016-06-23 15:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Eric Blake, Eduardo Habkost, Stefan Hajnoczi

A new event attribute 'cpu_id' is added to have a separate ID
space ('TRACE_VCPU_*') for all events with the 'vcpu' property.

These are later used to identify which events are enabled on each vCPU.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 scripts/tracetool/format/events_c.py |   11 +++++++++--
 scripts/tracetool/format/events_h.py |   12 +++++++++++-
 trace/control-internal.h             |   12 +++++++++++-
 trace/control.h                      |   17 +++++++++++++++++
 trace/event-internal.h               |    4 +++-
 5 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/scripts/tracetool/format/events_c.py b/scripts/tracetool/format/events_c.py
index 1cc6a49..4012063 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-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -28,8 +28,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 },',
+        if "vcpu" in e.properties:
+            vcpu_id = "TRACE_VCPU_" + e.name.upper()
+        else:
+            vcpu_id = "TRACE_VCPU_EVENT_COUNT"
+        out('    { .id = %(id)s, .vcpu_id = %(vcpu_id)s,'
+            ' .name = \"%(name)s\",'
+            ' .sstate = %(sstate)s },',
             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 4529263..a9da60b 100644
--- a/scripts/tracetool/format/events_h.py
+++ b/scripts/tracetool/format/events_h.py
@@ -32,13 +32,23 @@ 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:
+            out('    TRACE_VCPU_%s,' % e.name.upper())
+
+    out('    TRACE_VCPU_EVENT_COUNT',
+        '} TraceEventVCPUID;')
+
     # static state
     for e in events:
         if 'disable' in e.properties:
             enabled = 0
         else:
             enabled = 1
-        if "tcg-trans" in e.properties:
+        if "tcg-exec" in e.properties:
             # a single define for the two "sub-events"
             out('#define TRACE_%(name)s_ENABLED %(enabled)d',
                 name=e.original.name.upper(),
diff --git a/trace/control-internal.h b/trace/control-internal.h
index dcf67f5..5e0a5ab 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-2016 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.
@@ -40,6 +40,16 @@ static inline TraceEventID trace_event_get_id(TraceEvent *ev)
     return ev->id;
 }
 
+static inline TraceEventVCPUID trace_event_get_vcpu_id(TraceEvent *ev)
+{
+    return ev->vcpu_id;
+}
+
+static inline bool trace_event_is_vcpu(TraceEvent *ev)
+{
+    return ev->vcpu_id != TRACE_VCPU_EVENT_COUNT;
+}
+
 static inline const char * trace_event_get_name(TraceEvent *ev)
 {
     assert(ev != NULL);
diff --git a/trace/control.h b/trace/control.h
index e2ba6d4..d37bce7 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -86,6 +86,23 @@ static TraceEventID trace_event_count(void);
 static TraceEventID trace_event_get_id(TraceEvent *ev);
 
 /**
+ * trace_event_get_vcpu_id:
+ *
+ * Get the per-vCPU identifier of an event.
+ *
+ * Special value #TRACE_VCPU_EVENT_COUNT means the event is not vCPU-specific
+ * (does not have the "vcpu" property).
+ */
+static TraceEventVCPUID trace_event_get_vcpu_id(TraceEvent *ev);
+
+/**
+ * trace_event_is_vcpu:
+ *
+ * Whether this is a per-vCPU event.
+ */
+static bool trace_event_is_vcpu(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 86f6a51..202781a 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-2016 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.
+ * @vcpu_id: Unique per-vCPU event identifier.
  * @name: Event name.
  * @sstate: Static tracing state.
  *
@@ -23,6 +24,7 @@
  */
 typedef struct TraceEvent {
     TraceEventID id;
+    TraceEventVCPUID vcpu_id;
     const char * name;
     const bool sstate;
 } TraceEvent;

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

* [Qemu-devel] [PATCH v6 2/7] disas: Remove unused macro '_'
  2016-06-23 15:21 [Qemu-devel] [PATCH v6 0/7] trace: Per-vCPU tracing states Lluís Vilanova
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 1/7] trace: Identify events with the 'vcpu' property Lluís Vilanova
@ 2016-06-23 15:21 ` Lluís Vilanova
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 3/7] [trivial] trace: Cosmetic changes on fast-path tracing Lluís Vilanova
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Lluís Vilanova @ 2016-06-23 15:21 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Eric Blake, Eduardo Habkost, Stefan Hajnoczi,
	Richard Henderson, Peter Maydell, Andrzej Zaborowski,
	Aurelien Jarno, Leon Alrae, Vassili Karpov (malc),
	David Gibson, Alexander Graf, Mark Cave-Ayland, Artyom Tarasenko,
	Blue Swirl, open list:ARM, open list:PowerPC

Eliminates a future compilation error when UI code includes the tracing
headers (indirectly pulling "disas/bfd.h" through "qom/cpu.h") and
GLib's i18n '_' macro.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 disas/alpha.c       |    6 +++---
 disas/arm.c         |    2 +-
 disas/i386.c        |    2 +-
 disas/m68k.c        |    4 ++--
 disas/mips.c        |   50 +++++++++++++++++++++++++-------------------------
 disas/ppc.c         |   22 +++++++++++-----------
 disas/sparc.c       |    6 +++---
 include/disas/bfd.h |    1 -
 8 files changed, 46 insertions(+), 47 deletions(-)

diff --git a/disas/alpha.c b/disas/alpha.c
index 44d00a3..b7b0ae0 100644
--- a/disas/alpha.c
+++ b/disas/alpha.c
@@ -521,7 +521,7 @@ static unsigned
 insert_bdisp(unsigned insn, int value, const char **errmsg)
 {
   if (errmsg != (const char **)NULL && (value & 3))
-    *errmsg = _("branch operand unaligned");
+    *errmsg = "branch operand unaligned";
   return insn | ((value / 4) & 0x1FFFFF);
 }
 
@@ -539,7 +539,7 @@ static unsigned
 insert_jhint(unsigned insn, int value, const char **errmsg)
 {
   if (errmsg != (const char **)NULL && (value & 3))
-    *errmsg = _("jump hint unaligned");
+    *errmsg = "jump hint unaligned";
   return insn | ((value / 4) & 0x3FFF);
 }
 
@@ -556,7 +556,7 @@ static unsigned
 insert_ev6hwjhint(unsigned insn, int value, const char **errmsg)
 {
   if (errmsg != (const char **)NULL && (value & 3))
-    *errmsg = _("jump hint unaligned");
+    *errmsg = "jump hint unaligned";
   return insn | ((value / 4) & 0x1FFF);
 }
 
diff --git a/disas/arm.c b/disas/arm.c
index 70da529..32f8ca9 100644
--- a/disas/arm.c
+++ b/disas/arm.c
@@ -1817,7 +1817,7 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
 			  func (stream, "e");
 			  break;
 			default:
-			  func (stream, _("<illegal precision>"));
+			  func (stream, "<illegal precision>");
 			  break;
 			}
 		      break;
diff --git a/disas/i386.c b/disas/i386.c
index c0e717a..57145d0 100644
--- a/disas/i386.c
+++ b/disas/i386.c
@@ -3406,7 +3406,7 @@ static const struct dis386 three_byte_table[][256] = {
   }
 };
 
-#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
+#define INTERNAL_DISASSEMBLER_ERROR "<internal disassembler error>"
 
 static void
 ckprefix (void)
diff --git a/disas/m68k.c b/disas/m68k.c
index 8f74ae1..8e7c3f7 100644
--- a/disas/m68k.c
+++ b/disas/m68k.c
@@ -1676,7 +1676,7 @@ print_insn_arg (const char *d,
 	  (*info->fprintf_func) (info->stream, "%%sfc");
 	else
 	  /* xgettext:c-format */
-	  (*info->fprintf_func) (info->stream, _("<function code %d>"), fc);
+	  (*info->fprintf_func) (info->stream, "<function code %d>", fc);
       }
       break;
 
@@ -1827,7 +1827,7 @@ match_insn_m68k (bfd_vma memaddr,
 	{
 	  info->fprintf_func (info->stream,
 			      /* xgettext:c-format */
-			      _("<internal error in opcode table: %s %s>\n"),
+			      "<internal error in opcode table: %s %s>\n",
 			      best->name,  best->args);
 	  info->fprintf_func = save_printer;
 	  info->print_address_func = save_print_address;
diff --git a/disas/mips.c b/disas/mips.c
index 249931b..97f661a 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -4257,7 +4257,7 @@ print_insn_args (const char *d,
 	    case '\0':
 	      /* xgettext:c-format */
 	      (*info->fprintf_func) (info->stream,
-				     _("# internal error, incomplete extension sequence (+)"));
+				     "# internal error, incomplete extension sequence (+)");
 	      return;
 
 	    case 'A':
@@ -4515,7 +4515,7 @@ print_insn_args (const char *d,
 	    default:
 	      /* xgettext:c-format */
 	      (*info->fprintf_func) (info->stream,
-				     _("# internal error, undefined extension sequence (+%c)"),
+				     "# internal error, undefined extension sequence (+%c)",
 				     *d);
 	      return;
 	    }
@@ -4875,7 +4875,7 @@ print_insn_args (const char *d,
 	default:
 	  /* xgettext:c-format */
 	  (*info->fprintf_func) (info->stream,
-				 _("# internal error, undefined modifier(%c)"),
+				 "# internal error, undefined modifier(%c)",
 				 *d);
 	  return;
 	}
@@ -5739,7 +5739,7 @@ print_mips16_insn_arg (char type,
       /* xgettext:c-format */
       (*info->fprintf_func)
 	(info->stream,
-	 _("# internal disassembler error, unrecognised modifier (%c)"),
+	 "# internal disassembler error, unrecognised modifier (%c)",
 	 type);
       abort ();
     }
@@ -5750,51 +5750,51 @@ print_mips_disassembler_options (FILE *stream)
 {
   unsigned int i;
 
-  fprintf (stream, _("\n\
+  fprintf (stream, "\n\
 The following MIPS specific disassembler options are supported for use\n\
-with the -M switch (multiple options should be separated by commas):\n"));
+with the -M switch (multiple options should be separated by commas):\n");
 
-  fprintf (stream, _("\n\
+  fprintf (stream, "\n\
   gpr-names=ABI            Print GPR names according to  specified ABI.\n\
-                           Default: based on binary being disassembled.\n"));
+                           Default: based on binary being disassembled.\n");
 
-  fprintf (stream, _("\n\
+  fprintf (stream, "\n\
   fpr-names=ABI            Print FPR names according to specified ABI.\n\
-                           Default: numeric.\n"));
+                           Default: numeric.\n");
 
-  fprintf (stream, _("\n\
+  fprintf (stream, "\n\
   cp0-names=ARCH           Print CP0 register names according to\n\
                            specified architecture.\n\
-                           Default: based on binary being disassembled.\n"));
+                           Default: based on binary being disassembled.\n");
 
-  fprintf (stream, _("\n\
+  fprintf (stream, "\n\
   hwr-names=ARCH           Print HWR names according to specified\n\
 			   architecture.\n\
-                           Default: based on binary being disassembled.\n"));
+                           Default: based on binary being disassembled.\n");
 
-  fprintf (stream, _("\n\
+  fprintf (stream, "\n\
   reg-names=ABI            Print GPR and FPR names according to\n\
-                           specified ABI.\n"));
+                           specified ABI.\n");
 
-  fprintf (stream, _("\n\
+  fprintf (stream, "\n\
   reg-names=ARCH           Print CP0 register and HWR names according to\n\
-                           specified architecture.\n"));
+                           specified architecture.\n");
 
-  fprintf (stream, _("\n\
+  fprintf (stream, "\n\
   For the options above, the following values are supported for \"ABI\":\n\
-   "));
+   ");
   for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
     fprintf (stream, " %s", mips_abi_choices[i].name);
-  fprintf (stream, _("\n"));
+  fprintf (stream, "\n");
 
-  fprintf (stream, _("\n\
+  fprintf (stream, "\n\
   For the options above, The following values are supported for \"ARCH\":\n\
-   "));
+   ");
   for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
     if (*mips_arch_choices[i].name != '\0')
       fprintf (stream, " %s", mips_arch_choices[i].name);
-  fprintf (stream, _("\n"));
+  fprintf (stream, "\n");
 
-  fprintf (stream, _("\n"));
+  fprintf (stream, "\n");
 }
 #endif
diff --git a/disas/ppc.c b/disas/ppc.c
index 478332b..052cebe 100644
--- a/disas/ppc.c
+++ b/disas/ppc.c
@@ -1120,7 +1120,7 @@ insert_bo (unsigned long insn,
 	   const char **errmsg)
 {
   if (!valid_bo (value, dialect, 0))
-    *errmsg = _("invalid conditional option");
+    *errmsg = "invalid conditional option";
   return insn | ((value & 0x1f) << 21);
 }
 
@@ -1148,9 +1148,9 @@ insert_boe (unsigned long insn,
 	    const char **errmsg)
 {
   if (!valid_bo (value, dialect, 0))
-    *errmsg = _("invalid conditional option");
+    *errmsg = "invalid conditional option";
   else if ((value & 1) != 0)
-    *errmsg = _("attempt to set y bit when using + or - modifier");
+    *errmsg = "attempt to set y bit when using + or - modifier";
 
   return insn | ((value & 0x1f) << 21);
 }
@@ -1182,7 +1182,7 @@ insert_fxm (unsigned long insn,
     {
       if (value == 0 || (value & -value) != value)
 	{
-	  *errmsg = _("invalid mask field");
+	  *errmsg = "invalid mask field";
 	  value = 0;
 	}
     }
@@ -1208,7 +1208,7 @@ insert_fxm (unsigned long insn,
   /* Any other value on mfcr is an error.  */
   else if ((insn & (0x3ff << 1)) == 19 << 1)
     {
-      *errmsg = _("ignoring invalid mfcr mask");
+      *errmsg = "ignoring invalid mfcr mask";
       value = 0;
     }
 
@@ -1258,7 +1258,7 @@ insert_mbe (unsigned long insn,
 
   if (uval == 0)
     {
-      *errmsg = _("illegal bitmask");
+      *errmsg = "illegal bitmask";
       return insn;
     }
 
@@ -1293,7 +1293,7 @@ insert_mbe (unsigned long insn,
     me = 32;
 
   if (count != 2 && (count != 0 || ! last))
-    *errmsg = _("illegal bitmask");
+    *errmsg = "illegal bitmask";
 
   return insn | (mb << 6) | ((me - 1) << 1);
 }
@@ -1413,7 +1413,7 @@ insert_ram (unsigned long insn,
 	    const char **errmsg)
 {
   if ((unsigned long) value >= ((insn >> 21) & 0x1f))
-    *errmsg = _("index register in load range");
+    *errmsg = "index register in load range";
   return insn | ((value & 0x1f) << 16);
 }
 
@@ -1429,7 +1429,7 @@ insert_raq (unsigned long insn,
   long rtvalue = (insn & RT_MASK) >> 21;
 
   if (value == rtvalue)
-    *errmsg = _("source and target register operands must be different");
+    *errmsg = "source and target register operands must be different";
   return insn | ((value & 0x1f) << 16);
 }
 
@@ -1444,7 +1444,7 @@ insert_ras (unsigned long insn,
 	    const char **errmsg)
 {
   if (value == 0)
-    *errmsg = _("invalid register operand when updating");
+    *errmsg = "invalid register operand when updating";
   return insn | ((value & 0x1f) << 16);
 }
 
@@ -1526,7 +1526,7 @@ insert_sprg (unsigned long insn,
   if (value > 7
       || (value > 3
 	  && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0))
-    *errmsg = _("invalid sprg number");
+    *errmsg = "invalid sprg number";
 
   /* If this is mfsprg4..7 then use spr 260..263 which can be read in
      user mode.  Anything else must use spr 272..279.  */
diff --git a/disas/sparc.c b/disas/sparc.c
index 64bba8d..f120f4e 100644
--- a/disas/sparc.c
+++ b/disas/sparc.c
@@ -2494,7 +2494,7 @@ compare_opcodes (const void * a, const void * b)
       fprintf
         (stderr,
          /* xgettext:c-format */
-         _("Internal error:  bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
+         "Internal error:  bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
          op0->name, match0, lose0);
       op0->lose &= ~op0->match;
       lose0 = op0->lose;
@@ -2505,7 +2505,7 @@ compare_opcodes (const void * a, const void * b)
       fprintf
         (stderr,
          /* xgettext:c-format */
-         _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
+         "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
          op1->name, match1, lose1);
       op1->lose &= ~op1->match;
       lose1 = op1->lose;
@@ -2555,7 +2555,7 @@ compare_opcodes (const void * a, const void * b)
       else
         fprintf (stderr,
                  /* xgettext:c-format */
-                 _("Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"),
+                 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
                  op0->name, op1->name);
     }
 
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index a112e9c..a761d5b 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -477,7 +477,6 @@ int generic_symbol_at_address(bfd_vma, struct disassemble_info *);
   (INFO).disassembler_options = NULL, \
   (INFO).insn_info_valid = 0
 
-#define _(x) x
 #define ATTRIBUTE_UNUSED __attribute__((unused))
 
 /* from libbfd */

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

* [Qemu-devel] [PATCH v6 3/7] [trivial] trace: Cosmetic changes on fast-path tracing
  2016-06-23 15:21 [Qemu-devel] [PATCH v6 0/7] trace: Per-vCPU tracing states Lluís Vilanova
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 1/7] trace: Identify events with the 'vcpu' property Lluís Vilanova
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 2/7] disas: Remove unused macro '_' Lluís Vilanova
@ 2016-06-23 15:21 ` Lluís Vilanova
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 4/7] trace: Add per-vCPU tracing states for events with the 'vcpu' property Lluís Vilanova
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Lluís Vilanova @ 2016-06-23 15:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Eric Blake, Eduardo Habkost, Stefan Hajnoczi

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 trace/control-internal.h |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/trace/control-internal.h b/trace/control-internal.h
index 5e0a5ab..c5f5f3d 100644
--- a/trace/control-internal.h
+++ b/trace/control-internal.h
@@ -62,14 +62,17 @@ static inline bool trace_event_get_state_static(TraceEvent *ev)
     return ev->sstate;
 }
 
-static inline bool trace_event_get_state_dynamic_by_id(int id)
+static inline bool trace_event_get_state_dynamic_by_id(TraceEventID id)
 {
+    /* it's on fast path, avoid consistency checks (asserts) */
     return unlikely(trace_events_enabled_count) && trace_events_dstate[id];
 }
 
 static inline bool trace_event_get_state_dynamic(TraceEvent *ev)
 {
-    int id = trace_event_get_id(ev);
+    TraceEventID id;
+    assert(trace_event_get_state_static(ev));
+    id = trace_event_get_id(ev);
     return trace_event_get_state_dynamic_by_id(id);
 }
 

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

* [Qemu-devel] [PATCH v6 4/7] trace: Add per-vCPU tracing states for events with the 'vcpu' property
  2016-06-23 15:21 [Qemu-devel] [PATCH v6 0/7] trace: Per-vCPU tracing states Lluís Vilanova
                   ` (2 preceding siblings ...)
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 3/7] [trivial] trace: Cosmetic changes on fast-path tracing Lluís Vilanova
@ 2016-06-23 15:21 ` Lluís Vilanova
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 5/7] trace: Conditionally trace events based on their per-vCPU state Lluís Vilanova
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Lluís Vilanova @ 2016-06-23 15:21 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Eric Blake, Eduardo Habkost, Stefan Hajnoczi,
	Blue Swirl, Riku Voipio, Peter Crosthwaite, Richard Henderson

Each vCPU gets a 'trace_dstate' bitmap to control the per-vCPU dynamic
tracing state of events with the 'vcpu' property.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 bsd-user/main.c          |    1 +
 include/qom/cpu.h        |    6 +++++
 linux-user/main.c        |    1 +
 qom/cpu.c                |    1 +
 stubs/Makefile.objs      |    1 +
 stubs/trace-control.c    |   28 +++++++++++++++++++++
 trace/Makefile.objs      |    4 +++
 trace/control-internal.h |   28 ++++++++++++++++-----
 trace/control-target.c   |   53 ++++++++++++++++++++++++++++++++++++++++
 trace/control.c          |   29 ++++++++++++++++++++--
 trace/control.h          |   61 +++++++++++++++++++++++++++++++++++++++++++++-
 translate-all.h          |    3 ++
 vl.c                     |    1 +
 13 files changed, 207 insertions(+), 10 deletions(-)
 create mode 100644 stubs/trace-control.c
 create mode 100644 trace/control-target.c

diff --git a/bsd-user/main.c b/bsd-user/main.c
index a666345..4476b85 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -1135,6 +1135,7 @@ int main(int argc, char **argv)
         gdbserver_start (gdbstub_port);
         gdb_handlesig(cpu, 0);
     }
+    trace_init_vcpu_events();
     cpu_loop(env);
     /* never exits */
     return 0;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 32f3af3..c27489f 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -24,8 +24,10 @@
 #include "disas/bfd.h"
 #include "exec/hwaddr.h"
 #include "exec/memattrs.h"
+#include "qemu/bitmap.h"
 #include "qemu/queue.h"
 #include "qemu/thread.h"
+#include "trace/generated-events.h"
 
 typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
                                      void *opaque);
@@ -273,6 +275,7 @@ struct qemu_work_item {
  * @kvm_fd: vCPU file descriptor for KVM.
  * @work_mutex: Lock to prevent multiple access to queued_work_*.
  * @queued_work_first: First asynchronous work pending.
+ * @trace_dstate: Dynamic tracing state of events for this vCPU (bitmask).
  *
  * State of one CPU core or thread.
  */
@@ -340,6 +343,9 @@ struct CPUState {
     struct KVMState *kvm_state;
     struct kvm_run *kvm_run;
 
+    /* Used for events with 'vcpu' and *without* the 'disabled' properties */
+    DECLARE_BITMAP(trace_dstate, TRACE_VCPU_EVENT_COUNT);
+
     /* 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/linux-user/main.c b/linux-user/main.c
index 0fd3b19..e89b9c9 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -4804,6 +4804,7 @@ int main(int argc, char **argv, char **envp)
         }
         gdb_handlesig(cpu, 0);
     }
+    trace_init_vcpu_events();
     cpu_loop(env);
     /* never exits */
     return 0;
diff --git a/qom/cpu.c b/qom/cpu.c
index 751e992..929ecbe 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -330,6 +330,7 @@ static void cpu_common_initfn(Object *obj)
     qemu_mutex_init(&cpu->work_mutex);
     QTAILQ_INIT(&cpu->breakpoints);
     QTAILQ_INIT(&cpu->watchpoints);
+    bitmap_zero(cpu->trace_dstate, TRACE_VCPU_EVENT_COUNT);
 }
 
 static void cpu_common_finalize(Object *obj)
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 4b258a6..f742327 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -30,6 +30,7 @@ stub-obj-y += runstate-check.o
 stub-obj-y += set-fd-handler.o
 stub-obj-y += slirp.o
 stub-obj-y += sysbus.o
+stub-obj-y += trace-control.o
 stub-obj-y += uuid.o
 stub-obj-y += vm-stop.o
 stub-obj-y += vmstate.o
diff --git a/stubs/trace-control.c b/stubs/trace-control.c
new file mode 100644
index 0000000..fe59836
--- /dev/null
+++ b/stubs/trace-control.c
@@ -0,0 +1,28 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2014-2016 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/osdep.h"
+#include "trace/control.h"
+
+
+void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
+{
+    TraceEventID id;
+    assert(trace_event_get_state_static(ev));
+    id = trace_event_get_id(ev);
+    trace_events_enabled_count += state - trace_events_dstate[id];
+    trace_events_dstate[id] = state;
+}
+
+void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
+                                        TraceEvent *ev, bool state)
+{
+    /* should never be called on non-target binaries */
+    abort();
+}
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index cbe188e..4d91b3b 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -15,6 +15,7 @@ $(BUILD_DIR)/trace-events-all: $(trace-events-y:%=$(SRC_PATH)/%)
 # Auto-generated event descriptions for LTTng ust code
 
 ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust)
+
 $(obj)/generated-ust-provider.h: $(obj)/generated-ust-provider.h-timestamp
 	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
 $(obj)/generated-ust-provider.h-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
@@ -33,6 +34,7 @@ $(obj)/generated-ust.c-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
 
 $(obj)/generated-events.h: $(obj)/generated-ust-provider.h
 $(obj)/generated-events.c: $(obj)/generated-ust.c
+
 endif
 
 ######################################################################
@@ -91,6 +93,7 @@ $(obj)/generated-tracers.o: $(obj)/generated-tracers.c $(obj)/generated-tracers.
 # but that gets picked up by QEMU's Makefile as an external dependency
 # rule file. So we use '.dtrace' instead
 ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace)
+
 $(obj)/generated-tracers-dtrace.dtrace: $(obj)/generated-tracers-dtrace.dtrace-timestamp
 	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
 $(obj)/generated-tracers-dtrace.dtrace-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
@@ -155,4 +158,5 @@ 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
 util-obj-y += qmp.o
diff --git a/trace/control-internal.h b/trace/control-internal.h
index c5f5f3d..70a75de 100644
--- a/trace/control-internal.h
+++ b/trace/control-internal.h
@@ -10,10 +10,13 @@
 #ifndef TRACE__CONTROL_INTERNAL_H
 #define TRACE__CONTROL_INTERNAL_H
 
+#include <stddef.h>                     /* size_t */
+
+#include "qom/cpu.h"
 
 
 extern TraceEvent trace_events[];
-extern bool trace_events_dstate[];
+extern uint16_t trace_events_dstate[];
 extern int trace_events_enabled_count;
 
 
@@ -76,13 +79,24 @@ static inline bool trace_event_get_state_dynamic(TraceEvent *ev)
     return trace_event_get_state_dynamic_by_id(id);
 }
 
-static inline void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
+static inline bool trace_event_get_vcpu_state_dynamic_by_vcpu_id(CPUState *vcpu,
+                                                                 TraceEventVCPUID id)
 {
-    int id = trace_event_get_id(ev);
-    assert(ev != NULL);
-    assert(trace_event_get_state_static(ev));
-    trace_events_enabled_count += state - trace_events_dstate[id];
-    trace_events_dstate[id] = state;
+    /* it's on fast path, avoid consistency checks (asserts) */
+    if (unlikely(trace_events_enabled_count)) {
+        return test_bit(id, vcpu->trace_dstate);
+    } else {
+        return false;
+    }
+}
+
+static inline bool trace_event_get_vcpu_state_dynamic(CPUState *vcpu,
+                                                      TraceEvent *ev)
+{
+    TraceEventVCPUID id;
+    assert(trace_event_is_vcpu(ev));
+    id = trace_event_get_vcpu_id(ev);
+    return trace_event_get_vcpu_state_dynamic_by_vcpu_id(vcpu, id);
 }
 
 #endif  /* TRACE__CONTROL_INTERNAL_H */
diff --git a/trace/control-target.c b/trace/control-target.c
new file mode 100644
index 0000000..74c029a
--- /dev/null
+++ b/trace/control-target.c
@@ -0,0 +1,53 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2014-2016 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/osdep.h"
+#include "cpu.h"
+#include "trace/control.h"
+#include "translate-all.h"
+
+
+void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
+{
+    CPUState *vcpu;
+    assert(trace_event_get_state_static(ev));
+    if (trace_event_is_vcpu(ev)) {
+        CPU_FOREACH(vcpu) {
+            trace_event_set_vcpu_state_dynamic(vcpu, ev, state);
+        }
+    } else {
+        TraceEventID id = trace_event_get_id(ev);
+        trace_events_enabled_count += state - trace_events_dstate[id];
+        trace_events_dstate[id] = state;
+    }
+}
+
+void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
+                                        TraceEvent *ev, bool state)
+{
+    TraceEventID id;
+    TraceEventVCPUID vcpu_id;
+    bool state_pre;
+    assert(trace_event_get_state_static(ev));
+    assert(trace_event_is_vcpu(ev));
+    id = trace_event_get_id(ev);
+    vcpu_id = trace_event_get_vcpu_id(ev);
+    state_pre = test_bit(vcpu_id, vcpu->trace_dstate);
+    if (state_pre != state) {
+        if (state) {
+            trace_events_enabled_count++;
+            set_bit(vcpu_id, vcpu->trace_dstate);
+            trace_events_dstate[id]++;
+        } else {
+            trace_events_enabled_count--;
+            clear_bit(vcpu_id, vcpu->trace_dstate);
+            trace_events_dstate[id]--;
+        }
+    }
+}
diff --git a/trace/control.c b/trace/control.c
index e1556a3..55610fe 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -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-2016 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.
@@ -24,7 +24,14 @@
 #include "monitor/monitor.h"
 
 int trace_events_enabled_count;
-bool trace_events_dstate[TRACE_EVENT_COUNT];
+/*
+ * Interpretation depends on wether the event has the 'vcpu' property:
+ * - false: Boolean value indicating whether the event is active.
+ * - true : Integral counting the number of vCPUs that have this event enabled.
+ */
+uint16_t trace_events_dstate[TRACE_EVENT_COUNT];
+/* Marks events for late vCPU state init */
+static bool trace_events_dstate_init[TRACE_EVENT_COUNT];
 
 TraceEvent *trace_event_name(const char *name)
 {
@@ -113,7 +120,10 @@ static void do_trace_enable_events(const char *line_buf)
         TraceEvent *ev = NULL;
         while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) {
             if (trace_event_get_state_static(ev)) {
+                /* start tracing */
                 trace_event_set_state_dynamic(ev, enable);
+                /* mark for late vCPU init */
+                trace_events_dstate_init[ev->id] = true;
             }
         }
     } else {
@@ -125,7 +135,10 @@ static void do_trace_enable_events(const char *line_buf)
             error_report("WARNING: trace event '%s' is not traceable",
                          line_ptr);
         } else {
+            /* start tracing */
             trace_event_set_state_dynamic(ev, enable);
+            /* mark for late vCPU init */
+            trace_events_dstate_init[ev->id] = true;
         }
     }
 }
@@ -217,3 +230,15 @@ bool trace_init_backends(void)
 
     return true;
 }
+
+void trace_init_vcpu_events(void)
+{
+    TraceEvent *ev = NULL;
+    while ((ev = trace_event_pattern("*", ev)) != NULL) {
+        if (trace_event_is_vcpu(ev) &&
+            trace_event_get_state_static(ev) &&
+            trace_events_dstate_init[ev->id]) {
+            trace_event_set_state_dynamic(ev, true);
+        }
+    }
+}
diff --git a/trace/control.h b/trace/control.h
index d37bce7..5234a8e 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -124,6 +124,23 @@ static const char * trace_event_get_name(TraceEvent *ev);
     ((id ##_ENABLED) && trace_event_get_state_dynamic_by_id(id))
 
 /**
+ * trace_event_get_vcpu_state:
+ * @vcpu: Target vCPU.
+ * @id: Event identifier (TraceEventID).
+ * @vcpu_id: Per-vCPU event identifier (TraceEventVCPUID).
+ *
+ * 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_vcpu_state(vcpu, id, vcpu_id)                   \
+    ((id ##_ENABLED) && trace_event_get_vcpu_state_dynamic_by_vcpu_id(vcpu, vcpu_id))
+
+/**
  * trace_event_get_state_static:
  * @id: Event identifier.
  *
@@ -138,10 +155,19 @@ static bool trace_event_get_state_static(TraceEvent *ev);
  * trace_event_get_state_dynamic:
  *
  * Get the dynamic tracing state of an event.
+ *
+ * If the event has the 'vcpu' property, gets the OR'ed state of all vCPUs.
  */
 static bool trace_event_get_state_dynamic(TraceEvent *ev);
 
 /**
+ * trace_event_get_vcpu_state_dynamic:
+ *
+ * Get the dynamic tracing state of an event for the given vCPU.
+ */
+static bool trace_event_get_vcpu_state_dynamic(CPUState *vcpu, TraceEvent *ev);
+
+/**
  * trace_event_set_state:
  *
  * Set the tracing state of an event (only if possible).
@@ -155,13 +181,38 @@ static bool trace_event_get_state_dynamic(TraceEvent *ev);
     } while (0)
 
 /**
+ * trace_event_set_vcpu_state:
+ *
+ * Set the tracing state of an event for the given vCPU (only if not disabled).
+ */
+#define trace_event_set_vcpu_state(vcpu, id, state)                     \
+    do {                                                                \
+        if ((id ##_ENABLED)) {                                          \
+            TraceEvent *_e = trace_event_id(id);                        \
+            trace_event_set_vcpu_state_dynamic(vcpu, _e, state);        \
+        }                                                               \
+    } while (0)
+
+/**
  * trace_event_set_state_dynamic:
  *
  * Set the dynamic tracing state of an event.
  *
+ * If the event has the 'vcpu' property, sets the state on all vCPUs.
+ *
  * 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_vcpu_state_dynamic:
+ *
+ * Set the dynamic tracing state of an event for the given vCPU.
+ *
+ * Pre-condition: trace_event_get_vcpu_state_static(ev) == true
+ */
+void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
+                                        TraceEvent *ev, bool state);
 
 
 
@@ -214,6 +265,14 @@ void trace_list_events(void);
  */
 void trace_enable_events(const char *line_buf);
 
+/**
+ * trace_init_vcpu_events:
+ *
+ * Re-synchronize initial event state with vCPUs (which can be created after
+ * trace_init_events()).
+ */
+void trace_init_vcpu_events(void);
+
 
 #include "trace/control-internal.h"
 
diff --git a/translate-all.h b/translate-all.h
index ce6071b..ba8e4d6 100644
--- a/translate-all.h
+++ b/translate-all.h
@@ -19,6 +19,9 @@
 #ifndef TRANSLATE_ALL_H
 #define TRANSLATE_ALL_H
 
+#include "exec/exec-all.h"
+
+
 /* 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,
diff --git a/vl.c b/vl.c
index c85833a..0de7574 100644
--- a/vl.c
+++ b/vl.c
@@ -4625,6 +4625,7 @@ int main(int argc, char **argv, char **envp)
 
     os_setup_post();
 
+    trace_init_vcpu_events();
     main_loop();
     replay_disable_events();
 

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

* [Qemu-devel] [PATCH v6 5/7] trace: Conditionally trace events based on their per-vCPU state
  2016-06-23 15:21 [Qemu-devel] [PATCH v6 0/7] trace: Per-vCPU tracing states Lluís Vilanova
                   ` (3 preceding siblings ...)
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 4/7] trace: Add per-vCPU tracing states for events with the 'vcpu' property Lluís Vilanova
@ 2016-06-23 15:21 ` Lluís Vilanova
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 6/7] trace: Allow event name pattern in "info trace-events" Lluís Vilanova
  2016-06-23 15:22 ` [Qemu-devel] [PATCH v6 7/7] trace: Add QAPI/QMP interfaces to query and control per-vCPU tracing state Lluís Vilanova
  6 siblings, 0 replies; 10+ messages in thread
From: Lluís Vilanova @ 2016-06-23 15:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Eric Blake, Eduardo Habkost, Stefan Hajnoczi

Events with the 'vcpu' property are conditionally emitted according to
their per-vCPU state. Other events are emitted normally based on their
global tracing state.

Note that the per-vCPU condition check applies to all tracing backends.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 scripts/tracetool/backend/dtrace.py |    4 ++--
 scripts/tracetool/backend/ftrace.py |   20 ++++++++++----------
 scripts/tracetool/backend/log.py    |   26 ++++++++++++++++----------
 scripts/tracetool/backend/simple.py |   13 ++++++++++---
 scripts/tracetool/backend/ust.py    |    4 ++--
 scripts/tracetool/format/h.py       |   19 +++++++++++++++++--
 6 files changed, 57 insertions(+), 29 deletions(-)

diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
index fabfe99..ab9ecfa 100644
--- a/scripts/tracetool/backend/dtrace.py
+++ b/scripts/tracetool/backend/dtrace.py
@@ -6,7 +6,7 @@ DTrace/SystemTAP backend.
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -41,6 +41,6 @@ def generate_h_begin(events):
 
 
 def generate_h(event):
-    out('    QEMU_%(uppername)s(%(argnames)s);',
+    out('        QEMU_%(uppername)s(%(argnames)s);',
         uppername=event.name.upper(),
         argnames=", ".join(event.args.names()))
diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py
index d798c71..80dcf30 100644
--- a/scripts/tracetool/backend/ftrace.py
+++ b/scripts/tracetool/backend/ftrace.py
@@ -30,17 +30,17 @@ def generate_h(event):
     if len(event.args) > 0:
         argnames = ", " + argnames
 
-    out('    {',
-        '        char ftrace_buf[MAX_TRACE_STRLEN];',
-        '        int unused __attribute__ ((unused));',
-        '        int trlen;',
-        '        if (trace_event_get_state(%(event_id)s)) {',
-        '            trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,',
-        '                             "%(name)s " %(fmt)s "\\n" %(argnames)s);',
-        '            trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);',
-        '            unused = write(trace_marker_fd, ftrace_buf, trlen);',
+    out('        {',
+        '            char ftrace_buf[MAX_TRACE_STRLEN];',
+        '            int unused __attribute__ ((unused));',
+        '            int trlen;',
+        '            if (trace_event_get_state(%(event_id)s)) {',
+        '                trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,',
+        '                                 "%(name)s " %(fmt)s "\\n" %(argnames)s);',
+        '                trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);',
+        '                unused = write(trace_marker_fd, ftrace_buf, trlen);',
+        '            }',
         '        }',
-        '    }',
         name=event.name,
         args=event.args,
         event_id="TRACE_" + event.name.upper(),
diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py
index e409b73..b3ff064 100644
--- a/scripts/tracetool/backend/log.py
+++ b/scripts/tracetool/backend/log.py
@@ -6,7 +6,7 @@ Stderr built-in backend.
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -30,15 +30,21 @@ def generate_h(event):
     if len(event.args) > 0:
         argnames = ", " + argnames
 
-    out('    if (trace_event_get_state(%(event_id)s)) {',
-        '        struct timeval _now;',
-        '        gettimeofday(&_now, NULL);',
-        '        qemu_log_mask(LOG_TRACE, "%%d@%%zd.%%06zd:%(name)s " %(fmt)s "\\n",',
-        '                      getpid(),',
-        '                      (size_t)_now.tv_sec, (size_t)_now.tv_usec',
-        '                      %(argnames)s);',
-        '    }',
-        event_id="TRACE_" + event.name.upper(),
+    if "vcpu" in event.properties:
+        # already checked on the generic format code
+        cond = "true"
+    else:
+        cond = "trace_event_get_state(%s)" % ("TRACE_" + event.name.upper())
+
+    out('        if (%(cond)s) {',
+        '            struct timeval _now;',
+        '            gettimeofday(&_now, NULL);',
+        '            qemu_log_mask(LOG_TRACE, "%%d@%%zd.%%06zd:%(name)s " %(fmt)s "\\n",',
+        '                          getpid(),',
+        '                          (size_t)_now.tv_sec, (size_t)_now.tv_usec',
+        '                          %(argnames)s);',
+        '        }',
+        cond=cond,
         name=event.name,
         fmt=event.fmt.rstrip("\n"),
         argnames=argnames)
diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py
index 3246c20..1bccada 100644
--- a/scripts/tracetool/backend/simple.py
+++ b/scripts/tracetool/backend/simple.py
@@ -36,7 +36,7 @@ def generate_h_begin(events):
 
 
 def generate_h(event):
-    out('    _simple_%(api)s(%(args)s);',
+    out('        _simple_%(api)s(%(args)s);',
         api=event.api(),
         args=", ".join(event.args.names()))
 
@@ -68,16 +68,23 @@ def generate_c(event):
     if len(event.args) == 0:
         sizestr = '0'
 
+    event_id = 'TRACE_' + event.name.upper()
+    if "vcpu" in event.properties:
+        # already checked on the generic format code
+        cond = "true"
+    else:
+        cond = "trace_event_get_state(%s)" % event_id
 
     out('',
-        '    if (!trace_event_get_state(%(event_id)s)) {',
+        '    if (!%(cond)s) {',
         '        return;',
         '    }',
         '',
         '    if (trace_record_start(&rec, %(event_id)s, %(size_str)s)) {',
         '        return; /* Trace Buffer Full, Event Dropped ! */',
         '    }',
-        event_id='TRACE_' + event.name.upper(),
+        cond=cond,
+        event_id=event_id,
         size_str=sizestr)
 
     if len(event.args) > 0:
diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py
index 2f8f44a..ed4c227 100644
--- a/scripts/tracetool/backend/ust.py
+++ b/scripts/tracetool/backend/ust.py
@@ -6,7 +6,7 @@ LTTng User Space Tracing backend.
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -30,6 +30,6 @@ def generate_h(event):
     if len(event.args) > 0:
         argnames = ", " + argnames
 
-    out('    tracepoint(qemu, %(name)s%(tp_args)s);',
+    out('        tracepoint(qemu, %(name)s%(tp_args)s);',
         name=event.name,
         tp_args=argnames)
diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
index 0835406..3763e9a 100644
--- a/scripts/tracetool/format/h.py
+++ b/scripts/tracetool/format/h.py
@@ -23,21 +23,36 @@ def generate(events, backend):
         '#define TRACE__GENERATED_TRACERS_H',
         '',
         '#include "qemu-common.h"',
+        '#include "trace/control.h"',
         '')
 
     backend.generate_begin(events)
 
     for e in events:
+        if "vcpu" in e.properties:
+            trace_cpu = next(iter(e.args))[1]
+            cond = "trace_event_get_vcpu_state(%(cpu)s,"\
+                   " TRACE_%(id)s,"\
+                   " TRACE_VCPU_%(id)s)"\
+                   % dict(
+                       cpu=trace_cpu,
+                       id=e.name.upper())
+        else:
+            cond = "true"
+
         out('',
             'static inline void %(api)s(%(args)s)',
             '{',
+            '    if (%(cond)s) {',
             api=e.api(),
-            args=e.args)
+            args=e.args,
+            cond=cond)
 
         if "disable" not in e.properties:
             backend.generate(e)
 
-        out('}')
+        out('    }',
+            '}')
 
     backend.generate_end(events)
 

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

* [Qemu-devel] [PATCH v6 6/7] trace: Allow event name pattern in "info trace-events"
  2016-06-23 15:21 [Qemu-devel] [PATCH v6 0/7] trace: Per-vCPU tracing states Lluís Vilanova
                   ` (4 preceding siblings ...)
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 5/7] trace: Conditionally trace events based on their per-vCPU state Lluís Vilanova
@ 2016-06-23 15:21 ` Lluís Vilanova
  2016-06-24 14:49   ` Eric Blake
  2016-06-23 15:22 ` [Qemu-devel] [PATCH v6 7/7] trace: Add QAPI/QMP interfaces to query and control per-vCPU tracing state Lluís Vilanova
  6 siblings, 1 reply; 10+ messages in thread
From: Lluís Vilanova @ 2016-06-23 15:21 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Eric Blake, Eduardo Habkost, Stefan Hajnoczi,
	Markus Armbruster, Luiz Capitulino

Homogeinizes the command capabilities with QMP.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 hmp-commands-info.hx |    8 +++++---
 hmp.h                |    1 +
 monitor.c            |   31 ++++++++++++++++++++++++++++++-
 3 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 7da9e6c..3d07ca6 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -646,10 +646,12 @@ ETEXI
 
     {
         .name       = "trace-events",
-        .args_type  = "",
-        .params     = "",
-        .help       = "show available trace-events & their state",
+        .args_type  = "name:s?",
+        .params     = "[name]",
+        .help       = "show available trace-events & their state "
+                      "(name: event name pattern)",
         .mhandler.cmd = hmp_info_trace_events,
+        .command_completion = info_trace_events_completion,
     },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index f5d9749..0876ec0 100644
--- a/hmp.h
+++ b/hmp.h
@@ -115,6 +115,7 @@ void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
+void info_trace_events_completion(ReadLineState *rs, int nb_args, const char *str);
 void trace_event_completion(ReadLineState *rs, int nb_args, const char *str);
 void watchdog_action_completion(ReadLineState *rs, int nb_args,
                                 const char *str);
diff --git a/monitor.c b/monitor.c
index 6f960f1..7bd0f32 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1069,8 +1069,20 @@ static void hmp_info_cpustats(Monitor *mon, const QDict *qdict)
 
 static void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
 {
-    TraceEventInfoList *events = qmp_trace_event_get_state("*", NULL);
+    const char *name = qdict_get_try_str(qdict, "name");
+    TraceEventInfoList *events;
     TraceEventInfoList *elem;
+    Error *local_err = NULL;
+
+    if (name == NULL) {
+        name = "*";
+    }
+
+    events = qmp_trace_event_get_state(name, &local_err);
+    if (local_err) {
+        error_report_err(local_err);
+        return;
+    }
 
     for (elem = events; elem != NULL; elem = elem->next) {
         monitor_printf(mon, "%s : state %u\n",
@@ -3300,6 +3312,23 @@ void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
     }
 }
 
+void info_trace_events_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+    size_t len;
+
+    len = strlen(str);
+    readline_set_completion_index(rs, len);
+    if (nb_args == 2) {
+        TraceEventID id;
+        for (id = 0; id < trace_event_count(); id++) {
+            const char *event_name = trace_event_get_name(trace_event_id(id));
+            if (!strncmp(str, event_name, len)) {
+                readline_add_completion(rs, event_name);
+            }
+        }
+    }
+}
+
 void trace_event_completion(ReadLineState *rs, int nb_args, const char *str)
 {
     size_t len;

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

* [Qemu-devel] [PATCH v6 7/7] trace: Add QAPI/QMP interfaces to query and control per-vCPU tracing state
  2016-06-23 15:21 [Qemu-devel] [PATCH v6 0/7] trace: Per-vCPU tracing states Lluís Vilanova
                   ` (5 preceding siblings ...)
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 6/7] trace: Allow event name pattern in "info trace-events" Lluís Vilanova
@ 2016-06-23 15:22 ` Lluís Vilanova
  6 siblings, 0 replies; 10+ messages in thread
From: Lluís Vilanova @ 2016-06-23 15:22 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Eric Blake, Eduardo Habkost, Stefan Hajnoczi,
	Luiz Capitulino, Markus Armbruster

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hmp-commands-info.hx |    6 +-
 hmp-commands.hx      |    7 +-
 monitor.c            |   17 +++++-
 qapi/trace.json      |   32 +++++++++--
 qmp-commands.hx      |   35 +++++++++++-
 trace/qmp.c          |  148 ++++++++++++++++++++++++++++++++++++++++----------
 6 files changed, 202 insertions(+), 43 deletions(-)

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 3d07ca6..74446c6 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -646,10 +646,10 @@ ETEXI
 
     {
         .name       = "trace-events",
-        .args_type  = "name:s?",
-        .params     = "[name]",
+        .args_type  = "name:s?,vcpu:i?",
+        .params     = "[name] [vcpu]",
         .help       = "show available trace-events & their state "
-                      "(name: event name pattern)",
+                      "(name: event name pattern; vcpu: vCPU to query, default is any)",
         .mhandler.cmd = hmp_info_trace_events,
         .command_completion = info_trace_events_completion,
     },
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 98b4b1a..848efee 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -281,9 +281,10 @@ ETEXI
 
     {
         .name       = "trace-event",
-        .args_type  = "name:s,option:b",
-        .params     = "name on|off",
-        .help       = "changes status of a specific trace event",
+        .args_type  = "name:s,option:b,vcpu:i?",
+        .params     = "name on|off [vcpu]",
+        .help       = "changes status of a specific trace event "
+                      "(vcpu: vCPU to set, default is all)",
         .mhandler.cmd = hmp_trace_event,
         .command_completion = trace_event_completion,
     },
diff --git a/monitor.c b/monitor.c
index 7bd0f32..91a377b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -908,9 +908,16 @@ static void hmp_trace_event(Monitor *mon, const QDict *qdict)
 {
     const char *tp_name = qdict_get_str(qdict, "name");
     bool new_state = qdict_get_bool(qdict, "option");
+    int vcpu = qdict_get_try_int(qdict, "vcpu", -1);
     Error *local_err = NULL;
 
-    qmp_trace_event_set_state(tp_name, new_state, true, true, &local_err);
+    if (vcpu < -1) {
+        /* some user-provided negative number */
+        monitor_printf(mon, "argument vcpu must be positive");
+        return;
+    }
+
+    qmp_trace_event_set_state(tp_name, new_state, true, true, vcpu != -1, vcpu, &local_err);
     if (local_err) {
         error_report_err(local_err);
     }
@@ -1070,6 +1077,7 @@ static void hmp_info_cpustats(Monitor *mon, const QDict *qdict)
 static void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
 {
     const char *name = qdict_get_try_str(qdict, "name");
+    int vcpu = qdict_get_try_int(qdict, "vcpu", -1);
     TraceEventInfoList *events;
     TraceEventInfoList *elem;
     Error *local_err = NULL;
@@ -1077,8 +1085,13 @@ static void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
     if (name == NULL) {
         name = "*";
     }
+    if (vcpu < -1) {
+        /* some user-provided negative number */
+        monitor_printf(mon, "argument vcpu must be positive");
+        return;
+    }
 
-    events = qmp_trace_event_get_state(name, &local_err);
+    events = qmp_trace_event_get_state(name, vcpu != -1, vcpu, &local_err);
     if (local_err) {
         error_report_err(local_err);
         return;
diff --git a/qapi/trace.json b/qapi/trace.json
index 01b0a52..2123a46 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-2016 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,14 @@
 #
 # @name: Event name.
 # @state: Tracing state.
+# @vcpu: Whether this is a per-vCPU event (since 2.7).
+#
+# An event is per-vCPU if it has the "vcpu" property in the "trace-events" file.
 #
 # Since 2.2
 ##
 { 'struct': 'TraceEventInfo',
-  'data': {'name': 'str', 'state': 'TraceEventState'} }
+  'data': {'name': 'str', 'state': 'TraceEventState', 'vcpu': 'bool'} }
 
 ##
 # @trace-event-get-state:
@@ -41,13 +44,23 @@
 # Query the state of events.
 #
 # @name: Event name pattern (case-sensitive glob).
+# @vcpu: #optional The vCPU to query (any by default; since 2.7).
 #
 # Returns: a list of @TraceEventInfo for the matching events
 #
+# An event is returned if:
+# - its name matches the @name pattern, and
+# - if @vcpu is given, the event has the "vcpu" property.
+#
+# Therefore, if @vcpu is given, the operation will only match per-vCPU events,
+# returning their state on the specified vCPU. Special case: if @name is an
+# exact match, @vcpu is given and the event does not have the "vcpu" property,
+# an error is returned.
+#
 # Since 2.2
 ##
 { 'command': 'trace-event-get-state',
-  'data': {'name': 'str'},
+  'data': {'name': 'str', '*vcpu': 'int'},
   'returns': ['TraceEventInfo'] }
 
 ##
@@ -58,8 +71,19 @@
 # @name: Event name pattern (case-sensitive glob).
 # @enable: Whether to enable tracing.
 # @ignore-unavailable: #optional Do not match unavailable events with @name.
+# @vcpu: #optional The vCPU to act upon (all by default; since 2.7).
+#
+# An event's state is modified if:
+# - its name matches the @name pattern, and
+# - if @vcpu is given, the event has the "vcpu" property.
+#
+# Therefore, if @vcpu is given, the operation will only match per-vCPU events,
+# setting their state on the specified vCPU. Special case: if @name is an exact
+# match, @vcpu is given and the event does not have the "vcpu" property, an
+# error is returned.
 #
 # Since 2.2
 ##
 { 'command': 'trace-event-set-state',
-  'data': {'name': 'str', 'enable': 'bool', '*ignore-unavailable': 'bool'} }
+  'data': {'name': 'str', 'enable': 'bool', '*ignore-unavailable': 'bool',
+           '*vcpu': 'int'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index b444c20..8fbee65 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -4703,7 +4703,7 @@ EQMP
 
     {
         .name       = "trace-event-get-state",
-        .args_type  = "name:s",
+        .args_type  = "name:s,vcpu:i?",
         .mhandler.cmd_new = qmp_marshal_trace_event_get_state,
     },
 
@@ -4713,6 +4713,20 @@ trace-event-get-state
 
 Query the state of events.
 
+Arguments:
+
+- "name": Event name pattern (json-string).
+- "vcpu": The vCPU to query, any vCPU by default (json-int, optional).
+
+An event is returned if:
+- its name matches the "name" pattern, and
+- if "vcpu" is given, the event has the "vcpu" property.
+
+Therefore, if "vcpu" is given, the operation will only match per-vCPU events,
+returning their state on the specified vCPU. Special case: if "name" is an exact
+match, "vcpu" is given and the event does not have the "vcpu" property, an error
+is returned.
+
 Example:
 
 -> { "execute": "trace-event-get-state", "arguments": { "name": "qemu_memalign" } }
@@ -4721,7 +4735,7 @@ EQMP
 
     {
         .name       = "trace-event-set-state",
-        .args_type  = "name:s,enable:b,ignore-unavailable:b?",
+        .args_type  = "name:s,enable:b,ignore-unavailable:b?,vcpu:i?",
         .mhandler.cmd_new = qmp_marshal_trace_event_set_state,
     },
 
@@ -4731,6 +4745,23 @@ trace-event-set-state
 
 Set the state of events.
 
+Arguments:
+
+- "name": Event name pattern (json-string).
+- "enable": Whether to enable or disable the event (json-bool).
+- "ignore-unavailable": Whether to ignore errors for events that cannot be
+  changed (json-bool, optional).
+- "vcpu": The vCPU to act upon, all vCPUs by default (json-int, optional).
+
+An event's state is modified if:
+- its name matches the "name" pattern, and
+- if "vcpu" is given, the event has the "vcpu" property.
+
+Therefore, if "vcpu" is given, the operation will only match per-vCPU events,
+setting their state on the specified vCPU. Special case: if "name" is an exact
+match, "vcpu" is given and the event does not have the "vcpu" property, an error
+is returned.
+
 Example:
 
 -> { "execute": "trace-event-set-state", "arguments": { "name": "qemu_memalign", "enable": "true" } }
diff --git a/trace/qmp.c b/trace/qmp.c
index 8aa2660..11d2564 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-2016 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.
@@ -12,63 +12,153 @@
 #include "trace/control.h"
 
 
-TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp)
+static CPUState *get_cpu(bool has_vcpu, int vcpu, Error **errp)
 {
+    if (has_vcpu) {
+        CPUState *cpu = qemu_get_cpu(vcpu);
+        if (cpu == NULL) {
+            error_setg(errp, "invalid vCPU index %u", vcpu);
+        }
+        return cpu;
+    } else {
+        return NULL;
+    }
+}
+
+static bool check_events(bool has_vcpu, bool ignore_unavailable, bool is_pattern,
+                         const char *name, Error **errp)
+{
+    if (!is_pattern) {
+        TraceEvent *ev = trace_event_name(name);
+
+        /* error for non-existing event */
+        if (ev == NULL) {
+            error_setg(errp, "unknown event \"%s\"", name);
+            return false;
+        }
+
+        /* error for non-vcpu event */
+        if (has_vcpu && !trace_event_is_vcpu(ev)) {
+            error_setg(errp, "event \"%s\" is not vCPU-specific", name);
+            return false;
+        }
+
+        /* error for unavailable event */
+        if (!ignore_unavailable && !trace_event_get_state_static(ev)) {
+            error_setg(errp, "event \"%s\" is disabled", name);
+            return false;
+        }
+
+        return true;
+    } else {
+        /* error for unavailable events */
+        TraceEvent *ev = NULL;
+        while ((ev = trace_event_pattern(name, ev)) != NULL) {
+            if (!ignore_unavailable && !trace_event_get_state_static(ev)) {
+                error_setg(errp, "event \"%s\" is disabled", trace_event_get_name(ev));
+                return false;
+            }
+        }
+        return true;
+    }
+}
+
+TraceEventInfoList *qmp_trace_event_get_state(const char *name,
+                                              bool has_vcpu, int64_t vcpu,
+                                              Error **errp)
+{
+    Error *err = NULL;
     TraceEventInfoList *events = NULL;
-    bool found = false;
     TraceEvent *ev;
+    bool is_pattern = trace_event_is_pattern(name);
+    CPUState *cpu;
 
+    /* Check provided vcpu */
+    cpu = get_cpu(has_vcpu, vcpu, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return NULL;
+    }
+
+    /* Check events */
+    if (!check_events(has_vcpu, true, is_pattern, name, errp)) {
+        return NULL;
+    }
+
+    /* Get states (all errors checked above) */
     ev = NULL;
     while ((ev = trace_event_pattern(name, ev)) != NULL) {
-        TraceEventInfoList *elem = g_new(TraceEventInfoList, 1);
+        TraceEventInfoList *elem;
+        bool is_vcpu = trace_event_is_vcpu(ev);
+        if (has_vcpu && !is_vcpu) {
+            continue;
+        }
+
+        elem = g_new(TraceEventInfoList, 1);
         elem->value = g_new(TraceEventInfo, 1);
+        elem->value->vcpu = is_vcpu;
         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;
+            if (has_vcpu) {
+                if (is_vcpu) {
+                    if (trace_event_get_vcpu_state_dynamic(cpu, ev)) {
+                        elem->value->state = TRACE_EVENT_STATE_ENABLED;
+                    } else {
+                        elem->value->state = TRACE_EVENT_STATE_DISABLED;
+                    }
+                }
+                /* else: already skipped above */
+            } else {
+                if (trace_event_get_state_dynamic(ev)) {
+                    elem->value->state = TRACE_EVENT_STATE_ENABLED;
+                } else {
+                    elem->value->state = TRACE_EVENT_STATE_DISABLED;
+                }
+            }
         }
         elem->next = events;
         events = elem;
-        found = true;
-    }
-
-    if (!found && !trace_event_is_pattern(name)) {
-        error_setg(errp, "unknown event \"%s\"", name);
     }
 
     return events;
 }
 
 void qmp_trace_event_set_state(const char *name, bool enable,
-                               bool has_ignore_unavailable,
-                               bool ignore_unavailable, Error **errp)
+                               bool has_ignore_unavailable, bool ignore_unavailable,
+                               bool has_vcpu, int64_t vcpu,
+                               Error **errp)
 {
-    bool found = false;
+    Error *err = NULL;
     TraceEvent *ev;
+    bool is_pattern = trace_event_is_pattern(name);
+    CPUState *cpu;
 
-    /* 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;
-        }
+    /* Check provided vcpu */
+    cpu = get_cpu(has_vcpu, vcpu, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
     }
-    if (!found && !trace_event_is_pattern(name)) {
-        error_setg(errp, "unknown event \"%s\"", name);
+
+    /* Check events */
+    if (!check_events(has_vcpu, has_ignore_unavailable && ignore_unavailable,
+                      is_pattern, name, errp)) {
         return;
     }
 
-    /* Apply changes */
+    /* Apply changes (all errors checked above) */
     ev = NULL;
     while ((ev = trace_event_pattern(name, ev)) != NULL) {
-        if (trace_event_get_state_static(ev)) {
+        if (!trace_event_get_state_static(ev) ||
+            (has_vcpu && !trace_event_is_vcpu(ev))) {
+            continue;
+        }
+        if (has_vcpu) {
+            trace_event_set_vcpu_state_dynamic(cpu, ev, enable);
+        } else {
             trace_event_set_state_dynamic(ev, enable);
         }
     }

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

* Re: [Qemu-devel] [PATCH v6 6/7] trace: Allow event name pattern in "info trace-events"
  2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 6/7] trace: Allow event name pattern in "info trace-events" Lluís Vilanova
@ 2016-06-24 14:49   ` Eric Blake
  2016-06-27  9:01     ` Lluís Vilanova
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Blake @ 2016-06-24 14:49 UTC (permalink / raw)
  To: Lluís Vilanova, qemu-devel
  Cc: Paolo Bonzini, Eduardo Habkost, Stefan Hajnoczi,
	Markus Armbruster, Luiz Capitulino

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

On 06/23/2016 09:21 AM, Lluís Vilanova wrote:
> Homogeinizes the command capabilities with QMP.

s/Homogeinizes/homogenizes/

> 
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
>  hmp-commands-info.hx |    8 +++++---
>  hmp.h                |    1 +
>  monitor.c            |   31 ++++++++++++++++++++++++++++++-
>  3 files changed, 36 insertions(+), 4 deletions(-)
> 

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
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] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v6 6/7] trace: Allow event name pattern in "info trace-events"
  2016-06-24 14:49   ` Eric Blake
@ 2016-06-27  9:01     ` Lluís Vilanova
  0 siblings, 0 replies; 10+ messages in thread
From: Lluís Vilanova @ 2016-06-27  9:01 UTC (permalink / raw)
  To: Eric Blake
  Cc: qemu-devel, Paolo Bonzini, Luiz Capitulino, Eduardo Habkost,
	Stefan Hajnoczi, Markus Armbruster

Eric Blake writes:

> On 06/23/2016 09:21 AM, Lluís Vilanova wrote:
>> Homogeinizes the command capabilities with QMP.

> s/Homogeinizes/homogenizes/

>> 
>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
>> ---
>> hmp-commands-info.hx |    8 +++++---
>> hmp.h                |    1 +
>> monitor.c            |   31 ++++++++++++++++++++++++++++++-
>> 3 files changed, 36 insertions(+), 4 deletions(-)
>> 

> Reviewed-by: Eric Blake <eblake@redhat.com>

Thanks. I'll resend a series today with an additional minor bugfix.

Cheers,
  Lluis

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

end of thread, other threads:[~2016-06-27  9:01 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-23 15:21 [Qemu-devel] [PATCH v6 0/7] trace: Per-vCPU tracing states Lluís Vilanova
2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 1/7] trace: Identify events with the 'vcpu' property Lluís Vilanova
2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 2/7] disas: Remove unused macro '_' Lluís Vilanova
2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 3/7] [trivial] trace: Cosmetic changes on fast-path tracing Lluís Vilanova
2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 4/7] trace: Add per-vCPU tracing states for events with the 'vcpu' property Lluís Vilanova
2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 5/7] trace: Conditionally trace events based on their per-vCPU state Lluís Vilanova
2016-06-23 15:21 ` [Qemu-devel] [PATCH v6 6/7] trace: Allow event name pattern in "info trace-events" Lluís Vilanova
2016-06-24 14:49   ` Eric Blake
2016-06-27  9:01     ` Lluís Vilanova
2016-06-23 15:22 ` [Qemu-devel] [PATCH v6 7/7] trace: Add QAPI/QMP interfaces to query and control per-vCPU tracing state Lluís Vilanova

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.