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
next prev 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.