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>,
	maneesh@linux.vnet.ibm.com, ananth@linux.vnet.ibm.com
Subject: [PATCH 3/3] Toggle tracepoint state
Date: Tue, 8 Jun 2010 12:38:58 +0530	[thread overview]
Message-ID: <20100608123858.6d7dc770@zephyr> (raw)
In-Reply-To: <20100608122803.6a684a5e@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.

At present this is done with a simple comparison -- there is scope 
for optimizations that can be employed here to speed this up.

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

diff --git a/monitor.c b/monitor.c
index fda29aa..1e05b38 100644
--- a/monitor.c
+++ b/monitor.c
@@ -547,7 +547,19 @@ 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");
+    const char *tp_state = qdict_get_str(qdict, "option");
 
+    if (!strncmp(tp_state, "on", 2))
+	change_tracepoint_state(tp_name, 1);
+    if (!strncmp(tp_state, "off", 3))
+	change_tracepoint_state(tp_name, 0);
+    return;
+}
+#endif
 static void user_monitor_complete(void *opaque, QObject *ret_data)
 {
     MonitorCompletionData *data = (MonitorCompletionData *)opaque; 
@@ -2783,6 +2795,15 @@ static const mon_cmd_t info_cmds[] = {
         .help       = "show roms",
         .mhandler.info = do_info_roms,
     },
+#ifdef CONFIG_SIMPLE_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 c604aec..36481ea 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -114,6 +114,8 @@ show migration status
 show balloon information
 @item info qtree
 show device tree
+@item info tracepoints
+show available tracepoints and their state
 @end table
 ETEXI
 
@@ -236,6 +238,20 @@ STEXI
 @item trace
 @findex trace
 show contents of trace buffer
+ETEXI
+
+    {
+        .name       = "tracepoint",
+        .args_type  = "name:s,option:s",
+        .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 8f33a81..75d2fca 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;
@@ -64,7 +84,7 @@ void trace5(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long
 }
 
 void do_info_trace(Monitor *mon) {
-    static unsigned int i, max_idx;
+    unsigned int i, max_idx;
 
     if (trace_idx)
         max_idx = trace_idx;
@@ -77,3 +97,36 @@ void do_info_trace(Monitor *mon) {
 	trace_buf[i].x3, trace_buf[i].x4, trace_buf[i].x5);
     return;
 }
+
+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);
+    return;
+}
+
+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);
+    /* TODO : This update might need to be protected by a memory barrier */
+    if (i >= 0)
+	trace_list[i].state = tstate;
+    return;
+}
diff --git a/tracetool b/tracetool
index 6c15154..cc2b22c 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>,
	maneesh@linux.vnet.ibm.com, ananth@linux.vnet.ibm.com
Subject: [Qemu-devel] [PATCH 3/3] Toggle tracepoint state
Date: Tue, 8 Jun 2010 12:38:58 +0530	[thread overview]
Message-ID: <20100608123858.6d7dc770@zephyr> (raw)
In-Reply-To: <20100608122803.6a684a5e@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.

At present this is done with a simple comparison -- there is scope 
for optimizations that can be employed here to speed this up.

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

diff --git a/monitor.c b/monitor.c
index fda29aa..1e05b38 100644
--- a/monitor.c
+++ b/monitor.c
@@ -547,7 +547,19 @@ 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");
+    const char *tp_state = qdict_get_str(qdict, "option");
 
+    if (!strncmp(tp_state, "on", 2))
+	change_tracepoint_state(tp_name, 1);
+    if (!strncmp(tp_state, "off", 3))
+	change_tracepoint_state(tp_name, 0);
+    return;
+}
+#endif
 static void user_monitor_complete(void *opaque, QObject *ret_data)
 {
     MonitorCompletionData *data = (MonitorCompletionData *)opaque; 
@@ -2783,6 +2795,15 @@ static const mon_cmd_t info_cmds[] = {
         .help       = "show roms",
         .mhandler.info = do_info_roms,
     },
+#ifdef CONFIG_SIMPLE_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 c604aec..36481ea 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -114,6 +114,8 @@ show migration status
 show balloon information
 @item info qtree
 show device tree
+@item info tracepoints
+show available tracepoints and their state
 @end table
 ETEXI
 
@@ -236,6 +238,20 @@ STEXI
 @item trace
 @findex trace
 show contents of trace buffer
+ETEXI
+
+    {
+        .name       = "tracepoint",
+        .args_type  = "name:s,option:s",
+        .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 8f33a81..75d2fca 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;
@@ -64,7 +84,7 @@ void trace5(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long
 }
 
 void do_info_trace(Monitor *mon) {
-    static unsigned int i, max_idx;
+    unsigned int i, max_idx;
 
     if (trace_idx)
         max_idx = trace_idx;
@@ -77,3 +97,36 @@ void do_info_trace(Monitor *mon) {
 	trace_buf[i].x3, trace_buf[i].x4, trace_buf[i].x5);
     return;
 }
+
+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);
+    return;
+}
+
+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);
+    /* TODO : This update might need to be protected by a memory barrier */
+    if (i >= 0)
+	trace_list[i].state = tstate;
+    return;
+}
diff --git a/tracetool b/tracetool
index 6c15154..cc2b22c 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-08  7:09 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-08  6:58 [PATCH 0/3] Monitor commands for 'simple' trace backend Prerna Saxena
2010-06-08  6:58 ` [Qemu-devel] " Prerna Saxena
2010-06-08  7:01 ` [PATCH 1/3] export tdb_hash() Prerna Saxena
2010-06-08  7:01   ` [Qemu-devel] " Prerna Saxena
2010-06-09 20:35   ` Luiz Capitulino
2010-06-09 20:35     ` Luiz Capitulino
2010-06-11 10:32     ` Prerna Saxena
2010-06-11 10:32       ` Prerna Saxena
2010-06-08  7:04 ` [PATCH 2/3] Monitor command 'trace' Prerna Saxena
2010-06-08  7:04   ` [Qemu-devel] " Prerna Saxena
2010-06-09 20:37   ` Luiz Capitulino
2010-06-09 20:37     ` Luiz Capitulino
2010-06-11 10:46     ` Prerna Saxena
2010-06-11 10:46       ` Prerna Saxena
2010-06-08  7:08 ` Prerna Saxena [this message]
2010-06-08  7:08   ` [Qemu-devel] [PATCH 3/3] Toggle tracepoint state Prerna Saxena
2010-06-09 20:43   ` Luiz Capitulino
2010-06-09 20:43     ` Luiz Capitulino
2010-06-11 10:57     ` Prerna Saxena
2010-06-11 10:57       ` Prerna Saxena
  -- strict thread matches above, loose matches on Subject: below --
2010-06-16 12:35 [PATCH 0/3] Monitor support QEMU trace framework Prerna Saxena
2010-06-16 12:44 ` [PATCH 3/3] Toggle tracepoint state Prerna Saxena
2010-06-17 16:03   ` Stefan Hajnoczi

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=20100608123858.6d7dc770@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=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.