All of lore.kernel.org
 help / color / mirror / Atom feed
From: Prerna Saxena <prerna@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: Anthony Liguori <aliguori@us.ibm.com>,
	Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>,
	kvm@vger.kernel.org, Jan Kiszka <jan.kiszka@siemens.com>,
	Luiz Capitulino <lcapitulino@redhat.com>,
	maneesh@linux.vnet.ibm.com, ananth@linux.vnet.ibm.com
Subject: [RFC v2] [PATCH 3/3] Toggle tracepoint state
Date: Fri, 11 Jun 2010 00:54:27 +0530	[thread overview]
Message-ID: <20100611005427.4e76c315@zephyr> (raw)
In-Reply-To: <20100611003811.2635fa5d@zephyr>

This patch adds support for dynamically enabling/disabling of tracepoints.
Monitor commands added :
1) info tracepoints 		: to view all available tracepoints and 
				  their state.
2) tracepoint NAME on|off 	: to enable/disable data logging from a 
				  given tracepoint.
				  Eg, tracepoint paio_submit off 
				  	disables logging of data when 
					paio_submit is hit.

For now it is a simple comparison, I'm exploring optimizations that can 
be employed to make this faster.

Signed-off-by: Prerna Saxena <prerna@linux.vnet.ibm.com>
---
 monitor.c       |   16 +++++++++++++++-
 qemu-monitor.hx |   18 ++++++++++++++++++
 simpletrace.c   |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 tracetool       |   30 ++++++++++++++++++++++++++----
 vl.c            |    6 ++++++
 5 files changed, 118 insertions(+), 5 deletions(-)

diff --git a/monitor.c b/monitor.c
index 8b60830..e4c7bef 100644
--- a/monitor.c
+++ b/monitor.c
@@ -547,7 +547,14 @@ static void do_commit(Monitor *mon, const QDict *qdict)
         bdrv_commit(dinfo->bdrv);
     }
 }
-
+#ifdef CONFIG_SIMPLE_TRACE
+static void do_change_tracepoint_state(Monitor *mon, const QDict *qdict)
+{
+    const char *tp_name = qdict_get_str(qdict, "name");
+    bool new_state = qdict_get_bool(qdict, "option");
+    change_tracepoint_state(tp_name, new_state);
+}
+#endif
 static void user_monitor_complete(void *opaque, QObject *ret_data)
 {
     MonitorCompletionData *data = (MonitorCompletionData *)opaque; 
@@ -2791,6 +2798,13 @@ static const mon_cmd_t info_cmds[] = {
         .help       = "show current contents of trace buffer",
         .mhandler.info = do_info_trace,
     },
+    {
+        .name       = "tracepoints",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show available tracepoints & their state",
+        .mhandler.info = do_info_all_tracepoints,
+    },
 #endif
     {
         .name       = NULL,
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 766c30f..8540b8f 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -117,6 +117,8 @@ show device tree
 #ifdef CONFIG_SIMPLE_TRACE
 @item info trace
 show contents of trace buffer
+@item info tracepoints
+show available tracepoints and their state
 #endif
 @end table
 ETEXI
@@ -225,6 +227,22 @@ STEXI
 @item logfile @var{filename}
 @findex logfile
 Output logs to @var{filename}.
+#ifdef CONFIG_SIMPLE_TRACE
+ETEXI
+
+    {
+        .name       = "tracepoint",
+        .args_type  = "name:s,option:b",
+        .params     = "name on|off",
+        .help       = "changes status of a specific tracepoint",
+        .mhandler.cmd = do_change_tracepoint_state,
+    },
+
+STEXI
+@item tracepoint
+@findex tracepoint
+changes status of a tracepoint
+#endif
 ETEXI
 
     {
diff --git a/simpletrace.c b/simpletrace.c
index 00df45a..b601d24 100644
--- a/simpletrace.c
+++ b/simpletrace.c
@@ -3,6 +3,12 @@
 #include "trace.h"
 
 typedef struct {
+    char *tp_name;
+    bool state;
+    unsigned int hash;
+} Tracepoint;
+
+typedef struct {
     unsigned long event;
     unsigned long x1;
     unsigned long x2;
@@ -18,10 +24,24 @@ enum {
 static TraceRecord trace_buf[TRACE_BUF_LEN];
 static unsigned int trace_idx;
 static FILE *trace_fp;
+static Tracepoint trace_list[NR_TRACEPOINTS];
+
+void init_tracepoint(const char *tname, TraceEvent tevent) {
+    if (!tname || tevent > NR_TRACEPOINTS)
+        return;
+
+    trace_list[tevent].tp_name = (char*)qemu_malloc(strlen(tname)+1);
+    strncpy(trace_list[tevent].tp_name, tname, strlen(tname));
+    trace_list[tevent].hash = tdb_hash(tname);
+    trace_list[tevent].state = 1; /* Enable all by default */
+    return;
+}
 
 static void trace(TraceEvent event, unsigned long x1,
                   unsigned long x2, unsigned long x3,
                   unsigned long x4, unsigned long x5) {
+    if (!trace_list[event].state)
+        return;
     TraceRecord *rec = &trace_buf[trace_idx];
     rec->event = event;
     rec->x1 = x1;
@@ -74,3 +94,36 @@ void do_info_trace(Monitor *mon)
                           trace_buf[i].event, trace_buf[i].x1, trace_buf[i].x2,
                             trace_buf[i].x3, trace_buf[i].x4, trace_buf[i].x5);
 }
+
+void do_info_all_tracepoints(Monitor *mon)
+{
+    unsigned int i;
+    for (i=0; i<NR_TRACEPOINTS; i++)
+        monitor_printf(mon, "%s [Event ID %u] : state %u\n",
+                                trace_list[i].tp_name, i, trace_list[i].state);
+}
+
+static int find_tracepoint_by_name(const char *tname)
+{
+    unsigned int i, name_hash;
+
+    if (!tname)
+        return -1;
+
+    name_hash = tdb_hash(tname);
+
+    for (i=0; i<NR_TRACEPOINTS; i++)
+        if (trace_list[i].hash == name_hash &&
+                         !strncmp(trace_list[i].tp_name, tname, strlen(tname)))
+            return i;
+    return -1; /* indicates end of list reached without a match */
+}
+
+void change_tracepoint_state(const char *tname, bool tstate)
+{
+    int i;
+
+    i = find_tracepoint_by_name(tname);
+    if (i >= 0)
+        trace_list[i].state = tstate;
+}
diff --git a/tracetool b/tracetool
index 2c73bab..00af205 100755
--- a/tracetool
+++ b/tracetool
@@ -123,14 +123,20 @@ linetoc_end_nop()
 linetoh_begin_simple()
 {
     cat <<EOF
+#include <stdbool.h>
+
 typedef unsigned int TraceEvent;
 
+void init_tracepoint_table(void);
+void init_tracepoint(const char *tname, TraceEvent tevent);
 void trace1(TraceEvent event, unsigned long x1);
 void trace2(TraceEvent event, unsigned long x1, unsigned long x2);
 void trace3(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3);
 void trace4(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4);
 void trace5(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4, unsigned long x5);
 void do_info_trace(Monitor *mon);
+void do_info_all_tracepoints(Monitor *mon);
+void change_tracepoint_state(const char *tname, bool tstate);
 EOF
 
     simple_event_num=0
@@ -163,22 +169,38 @@ EOF
 
 linetoh_end_simple()
 {
-    return
+    cat <<EOF
+#define NR_TRACEPOINTS $simple_event_num
+EOF
 }
 
 linetoc_begin_simple()
 {
-    return
+    cat <<EOF
+#include "trace.h"
+
+void init_tracepoint_table(void) {
+EOF
+    simple_event_num=0
+
 }
 
 linetoc_simple()
 {
-    return
+    local name
+    name=$(get_name "$1")
+    cat <<EOF
+init_tracepoint("$name", $simple_event_num);
+EOF
+    simple_event_num=$((simple_event_num + 1))
 }
 
 linetoc_end_simple()
 {
-    return
+    cat <<EOF
+return;
+}
+EOF
 }
 
 linetoh_begin_ust()
diff --git a/vl.c b/vl.c
index 328395e..dd07904 100644
--- a/vl.c
+++ b/vl.c
@@ -163,6 +163,9 @@ int main(int argc, char **argv)
 #include "cpus.h"
 #include "arch_init.h"
 
+#ifdef CONFIG_SIMPLE_TRACE
+#include "trace.h"
+#endif
 //#define DEBUG_NET
 //#define DEBUG_SLIRP
 
@@ -3604,6 +3607,9 @@ int main(int argc, char **argv, char **envp)
     if (net_init_clients() < 0) {
         exit(1);
     }
+#ifdef CONFIG_SIMPLE_TRACE
+    init_tracepoint_table();
+#endif
 
     /* init the bluetooth world */
     if (foreach_device_config(DEV_BT, bt_parse))
-- 
1.6.2.5



-- 
Prerna Saxena

Linux Technology Centre,
IBM Systems and Technology Lab,
Bangalore, India


WARNING: multiple messages have this Message-ID (diff)
From: Prerna Saxena <prerna@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: Anthony Liguori <aliguori@us.ibm.com>,
	Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>,
	kvm@vger.kernel.org, Jan Kiszka <jan.kiszka@siemens.com>,
	Luiz Capitulino <lcapitulino@redhat.com>,
	maneesh@linux.vnet.ibm.com, ananth@linux.vnet.ibm.com
Subject: [Qemu-devel] [RFC v2] [PATCH 3/3] Toggle tracepoint state
Date: Fri, 11 Jun 2010 00:54:27 +0530	[thread overview]
Message-ID: <20100611005427.4e76c315@zephyr> (raw)
In-Reply-To: <20100611003811.2635fa5d@zephyr>

This patch adds support for dynamically enabling/disabling of tracepoints.
Monitor commands added :
1) info tracepoints 		: to view all available tracepoints and 
				  their state.
2) tracepoint NAME on|off 	: to enable/disable data logging from a 
				  given tracepoint.
				  Eg, tracepoint paio_submit off 
				  	disables logging of data when 
					paio_submit is hit.

For now it is a simple comparison, I'm exploring optimizations that can 
be employed to make this faster.

Signed-off-by: Prerna Saxena <prerna@linux.vnet.ibm.com>
---
 monitor.c       |   16 +++++++++++++++-
 qemu-monitor.hx |   18 ++++++++++++++++++
 simpletrace.c   |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 tracetool       |   30 ++++++++++++++++++++++++++----
 vl.c            |    6 ++++++
 5 files changed, 118 insertions(+), 5 deletions(-)

diff --git a/monitor.c b/monitor.c
index 8b60830..e4c7bef 100644
--- a/monitor.c
+++ b/monitor.c
@@ -547,7 +547,14 @@ static void do_commit(Monitor *mon, const QDict *qdict)
         bdrv_commit(dinfo->bdrv);
     }
 }
-
+#ifdef CONFIG_SIMPLE_TRACE
+static void do_change_tracepoint_state(Monitor *mon, const QDict *qdict)
+{
+    const char *tp_name = qdict_get_str(qdict, "name");
+    bool new_state = qdict_get_bool(qdict, "option");
+    change_tracepoint_state(tp_name, new_state);
+}
+#endif
 static void user_monitor_complete(void *opaque, QObject *ret_data)
 {
     MonitorCompletionData *data = (MonitorCompletionData *)opaque; 
@@ -2791,6 +2798,13 @@ static const mon_cmd_t info_cmds[] = {
         .help       = "show current contents of trace buffer",
         .mhandler.info = do_info_trace,
     },
+    {
+        .name       = "tracepoints",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show available tracepoints & their state",
+        .mhandler.info = do_info_all_tracepoints,
+    },
 #endif
     {
         .name       = NULL,
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 766c30f..8540b8f 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -117,6 +117,8 @@ show device tree
 #ifdef CONFIG_SIMPLE_TRACE
 @item info trace
 show contents of trace buffer
+@item info tracepoints
+show available tracepoints and their state
 #endif
 @end table
 ETEXI
@@ -225,6 +227,22 @@ STEXI
 @item logfile @var{filename}
 @findex logfile
 Output logs to @var{filename}.
+#ifdef CONFIG_SIMPLE_TRACE
+ETEXI
+
+    {
+        .name       = "tracepoint",
+        .args_type  = "name:s,option:b",
+        .params     = "name on|off",
+        .help       = "changes status of a specific tracepoint",
+        .mhandler.cmd = do_change_tracepoint_state,
+    },
+
+STEXI
+@item tracepoint
+@findex tracepoint
+changes status of a tracepoint
+#endif
 ETEXI
 
     {
diff --git a/simpletrace.c b/simpletrace.c
index 00df45a..b601d24 100644
--- a/simpletrace.c
+++ b/simpletrace.c
@@ -3,6 +3,12 @@
 #include "trace.h"
 
 typedef struct {
+    char *tp_name;
+    bool state;
+    unsigned int hash;
+} Tracepoint;
+
+typedef struct {
     unsigned long event;
     unsigned long x1;
     unsigned long x2;
@@ -18,10 +24,24 @@ enum {
 static TraceRecord trace_buf[TRACE_BUF_LEN];
 static unsigned int trace_idx;
 static FILE *trace_fp;
+static Tracepoint trace_list[NR_TRACEPOINTS];
+
+void init_tracepoint(const char *tname, TraceEvent tevent) {
+    if (!tname || tevent > NR_TRACEPOINTS)
+        return;
+
+    trace_list[tevent].tp_name = (char*)qemu_malloc(strlen(tname)+1);
+    strncpy(trace_list[tevent].tp_name, tname, strlen(tname));
+    trace_list[tevent].hash = tdb_hash(tname);
+    trace_list[tevent].state = 1; /* Enable all by default */
+    return;
+}
 
 static void trace(TraceEvent event, unsigned long x1,
                   unsigned long x2, unsigned long x3,
                   unsigned long x4, unsigned long x5) {
+    if (!trace_list[event].state)
+        return;
     TraceRecord *rec = &trace_buf[trace_idx];
     rec->event = event;
     rec->x1 = x1;
@@ -74,3 +94,36 @@ void do_info_trace(Monitor *mon)
                           trace_buf[i].event, trace_buf[i].x1, trace_buf[i].x2,
                             trace_buf[i].x3, trace_buf[i].x4, trace_buf[i].x5);
 }
+
+void do_info_all_tracepoints(Monitor *mon)
+{
+    unsigned int i;
+    for (i=0; i<NR_TRACEPOINTS; i++)
+        monitor_printf(mon, "%s [Event ID %u] : state %u\n",
+                                trace_list[i].tp_name, i, trace_list[i].state);
+}
+
+static int find_tracepoint_by_name(const char *tname)
+{
+    unsigned int i, name_hash;
+
+    if (!tname)
+        return -1;
+
+    name_hash = tdb_hash(tname);
+
+    for (i=0; i<NR_TRACEPOINTS; i++)
+        if (trace_list[i].hash == name_hash &&
+                         !strncmp(trace_list[i].tp_name, tname, strlen(tname)))
+            return i;
+    return -1; /* indicates end of list reached without a match */
+}
+
+void change_tracepoint_state(const char *tname, bool tstate)
+{
+    int i;
+
+    i = find_tracepoint_by_name(tname);
+    if (i >= 0)
+        trace_list[i].state = tstate;
+}
diff --git a/tracetool b/tracetool
index 2c73bab..00af205 100755
--- a/tracetool
+++ b/tracetool
@@ -123,14 +123,20 @@ linetoc_end_nop()
 linetoh_begin_simple()
 {
     cat <<EOF
+#include <stdbool.h>
+
 typedef unsigned int TraceEvent;
 
+void init_tracepoint_table(void);
+void init_tracepoint(const char *tname, TraceEvent tevent);
 void trace1(TraceEvent event, unsigned long x1);
 void trace2(TraceEvent event, unsigned long x1, unsigned long x2);
 void trace3(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3);
 void trace4(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4);
 void trace5(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4, unsigned long x5);
 void do_info_trace(Monitor *mon);
+void do_info_all_tracepoints(Monitor *mon);
+void change_tracepoint_state(const char *tname, bool tstate);
 EOF
 
     simple_event_num=0
@@ -163,22 +169,38 @@ EOF
 
 linetoh_end_simple()
 {
-    return
+    cat <<EOF
+#define NR_TRACEPOINTS $simple_event_num
+EOF
 }
 
 linetoc_begin_simple()
 {
-    return
+    cat <<EOF
+#include "trace.h"
+
+void init_tracepoint_table(void) {
+EOF
+    simple_event_num=0
+
 }
 
 linetoc_simple()
 {
-    return
+    local name
+    name=$(get_name "$1")
+    cat <<EOF
+init_tracepoint("$name", $simple_event_num);
+EOF
+    simple_event_num=$((simple_event_num + 1))
 }
 
 linetoc_end_simple()
 {
-    return
+    cat <<EOF
+return;
+}
+EOF
 }
 
 linetoh_begin_ust()
diff --git a/vl.c b/vl.c
index 328395e..dd07904 100644
--- a/vl.c
+++ b/vl.c
@@ -163,6 +163,9 @@ int main(int argc, char **argv)
 #include "cpus.h"
 #include "arch_init.h"
 
+#ifdef CONFIG_SIMPLE_TRACE
+#include "trace.h"
+#endif
 //#define DEBUG_NET
 //#define DEBUG_SLIRP
 
@@ -3604,6 +3607,9 @@ int main(int argc, char **argv, char **envp)
     if (net_init_clients() < 0) {
         exit(1);
     }
+#ifdef CONFIG_SIMPLE_TRACE
+    init_tracepoint_table();
+#endif
 
     /* init the bluetooth world */
     if (foreach_device_config(DEV_BT, bt_parse))
-- 
1.6.2.5



-- 
Prerna Saxena

Linux Technology Centre,
IBM Systems and Technology Lab,
Bangalore, India

  parent reply	other threads:[~2010-06-10 19:24 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-10 19:08 [RFC v2] [PATCH 0/3] Monitor Support for 'simple' trace backend Prerna Saxena
2010-06-10 19:08 ` [Qemu-devel] " Prerna Saxena
2010-06-10 19:15 ` [RFC v2] [PATCH 1/3] Export tdb_hash() Prerna Saxena
2010-06-10 19:15   ` [Qemu-devel] " Prerna Saxena
2010-06-11 17:54   ` Luiz Capitulino
2010-06-11 17:54     ` [Qemu-devel] " Luiz Capitulino
2010-06-10 19:20 ` [RFC v2] [PATCH 2/3] Monitor command 'info trace' Prerna Saxena
2010-06-10 19:20   ` [Qemu-devel] " Prerna Saxena
2010-06-10 19:24 ` Prerna Saxena [this message]
2010-06-10 19:24   ` [Qemu-devel] [RFC v2] [PATCH 3/3] Toggle tracepoint state Prerna Saxena
2010-06-11 11:42 ` [Qemu-devel] [RFC v2] [PATCH 0/3] Monitor Support for 'simple' trace backend Markus Armbruster
2010-06-11 11:42   ` Markus Armbruster
2010-06-11 12:08   ` Jan Kiszka
2010-06-11 12:08     ` Jan Kiszka
2010-06-11 17:56     ` Luiz Capitulino
2010-06-11 17:56       ` Luiz Capitulino

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100611005427.4e76c315@zephyr \
    --to=prerna@linux.vnet.ibm.com \
    --cc=aliguori@us.ibm.com \
    --cc=ananth@linux.vnet.ibm.com \
    --cc=jan.kiszka@siemens.com \
    --cc=kvm@vger.kernel.org \
    --cc=lcapitulino@redhat.com \
    --cc=maneesh@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.