Signed-off by : Prerna (prerna@linux.vnet.ibm.com)
===================================================================
@@ -55,7 +55,9 @@
#include "json-streamer.h"
#include "json-parser.h"
#include "osdep.h"
-
+#ifdef CONFIG_QEMU_TRACE
+#include "tracepoint.h"
+#endif
//#define DEBUG
//#define DEBUG_COMPLETION
@@ -145,6 +147,10 @@ struct Monitor {
#ifdef CONFIG_DEBUG_MONITOR
int print_calls_nr;
#endif
+#ifdef CONFIG_QEMU_TRACE
+ struct DebugBuffer *qemu_buf_ptr;
+#endif
+
QError *error;
QLIST_HEAD(,mon_fd_t) fds;
QLIST_ENTRY(Monitor) entry;
@@ -1198,6 +1204,63 @@ static void do_log(Monitor *mon, const Q
cpu_set_log(mask);
}
+#ifdef CONFIG_QEMU_TRACE
+static void do_trace(Monitor *mon, const QDict *qdict)
+{
+ const char *option = qdict_get_try_str(qdict, "option");
+ if (!option || !strncmp(option, "on", 3)) {
+ mon->qemu_buf_ptr = &qemu_buf;
+ initialize_buffer(mon->qemu_buf_ptr);
+ } else if (!strncmp(option, "off", 4)) {
+ mon->qemu_buf_ptr->enabled = 0;
+ } else {
+ monitor_printf(mon, "Invalid option %s\n", option);
+ }
+}
+
+static void do_tracepoint_status(Monitor *mon, const QDict *qdict)
+{
+ uint8_t status_num;
+ struct tracepoint *t;
+ const char *tp_name = qdict_get_str(qdict, "name");
+ const char *tp_state = qdict_get_str(qdict, "option");
+
+ if(!mon->qemu_buf_ptr || !mon->qemu_buf_ptr->enabled) {
+ monitor_printf(mon, "Tracing disabled. Use \"trace on\" before this\n");
+ return;
+ }
+ if(!strncmp(tp_state, "on", 3))
+ status_num = 1;
+ else {
+ if(!strncmp(tp_state, "off", 4))
+ status_num = 0;
+ else {
+ monitor_printf(mon, "Invalid option : %s. Use [on|off]\n",
+ tp_state);
+ return;
+ }
+ }
+ t = find_tracepoint_by_name(tp_name);
+ if(t == NULL) {
+ monitor_printf(mon, "Tracepoint %s does not exist\n", tp_name);
+ return;
+ }
+ if(t->state == status_num) {
+ monitor_printf(mon, "State of Tracepoint %s is already %s\n",
+ tp_name, tp_state);
+ return;
+ }
+ /* Do I need a spin_lock here ? */
+ t->state = status_num;
+ return;
+}
+#else /* CONFIG_QEMU_TRACE */
+static void do_tracepoint_status(Monitor *mon, const QDict *qdict)
+{
+ monitor_printf(mon, "Internal tracing not compiled\n");
+}
+#endif
+
static void do_singlestep(Monitor *mon, const QDict *qdict)
{
const char *option = qdict_get_try_str(qdict, "option");
@@ -2170,6 +2233,42 @@ static void do_info_profile(Monitor *mon
}
#endif
+#ifdef CONFIG_QEMU_TRACE
+
+static void qemu_dump_trace(Monitor *mon, struct DebugEntry *data)
+{
+ int i;
+
+ char *iter = (char *)data;
+ for (i=0; i<SLOT_SIZE/sizeof(int); i++)
+ monitor_printf(mon, "%c",iter[i]);
+ monitor_printf(mon, "\n");
+ return;
+}
+
+static void do_info_trace(Monitor *mon)
+{
+ struct DebugEntry data;
+ /* TODO : change def of read to have null return*/
+ if(!mon->qemu_buf_ptr || !mon->qemu_buf_ptr->enabled)
+ return;
+
+ while(1) {
+ if(!read_trace_from_buffer(mon->qemu_buf_ptr, &data))
+ break ;
+ /* qemu_dump_trace() is a simple hex dump */
+// qemu_dump_trace(mon, &data);
+ print_trace(&data, mon);
+ };
+ return;
+}
+#else /* CONFIG_QEMU_TRACE */
+static void do_info_trace(Monitor *mon)
+{
+ monitor_printf(mon, "Internal tracing not compiled\n");
+}
+#endif
+
/* Capture support */
static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
@@ -2779,6 +2878,20 @@ static const mon_cmd_t info_cmds[] = {
.mhandler.info = do_info_roms,
},
{
+ .name = "trace",
+ .args_type = "",
+ .params = "",
+ .help = "show contents of trace buffer",
+ .mhandler.info = do_info_trace,
+ },
+ {
+ .name = "tracepoint",
+ .args_type = "",
+ .params = "",
+ .help = "show contents of trace buffer",
+ .mhandler.info = do_info_tracepoint,
+ },
+ {
.name = NULL,
},
};
@@ -4633,6 +4746,9 @@ void monitor_init(CharDriverState *chr,
QLIST_INSERT_HEAD(&mon_list, mon, entry);
if (!default_mon || (flags & MONITOR_IS_DEFAULT))
default_mon = mon;
+
+ /* Disable trace buffer unless enabled */
+ mon->qemu_buf_ptr = NULL;
}
static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque)
===================================================================
@@ -0,0 +1,111 @@
+/*
+ * Trace buffer implementation for QEMU.
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Author:
+ * Prerna <prerna@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include<string.h>
+
+#include "trace-buffer.h"
+
+#define INCREMENT_INDEX(HEAD,IDX) (HEAD->IDX++) % HEAD->buf_size
+/* TODOS :
+ * functions for computing timestamps, etc
+ */
+
+/* Trace Buffer Manipulation Functions */
+
+/* Initialise the buffer.
+ * @head : pointer to the trace queue
+ */
+void initialize_buffer(struct DebugBuffer *head)
+{
+ if (!head) /* Buffer doesnt exist, do nothing */
+ return ;
+
+ head->buf_size = BUFFER_SIZE;
+ head->first = head->last = 0;
+ head->enabled = 1;
+ return;
+}
+
+/* Write trace data to buffer.
+ * @trace_queue : pointer to the trace queue.
+ * @data : data to be written.
+ * @len : Length of data to be written.
+ * @type : class of events.
+ * return : 0 for successful write.
+ * : -1 if size of data exceeds slot size.
+ */
+int write_trace_to_buffer(struct DebugBuffer *trace_queue,
+ uint32_t hash, uint8_t id, const void *data,
+ size_t len/*, EVENT_TYPE etype*/)
+{
+ int tmp;
+
+ /* Exit early if tracing is disabled */
+ if (!trace_queue || !trace_queue->enabled)
+ return -1;
+
+ /* Data not available or too large data */
+ if (!data || !len || len > EFFECTIVE_SLOT_SIZE - 5)
+ return -1;
+
+ /* NOTE : the buffer operates in overwrite mode */
+ tmp = trace_queue->last;
+ if ((trace_queue->last + 1) % trace_queue->buf_size
+ == trace_queue->first)
+ trace_queue->first = INCREMENT_INDEX(trace_queue, first);
+ trace_queue->last = INCREMENT_INDEX(trace_queue, last);
+
+ /* TODO: Placeholder for timestamp computation */
+
+ trace_queue->trace_buffer[tmp].metadata.write_complete = 0;
+ memcpy(trace_queue->trace_buffer[tmp].data, &hash, sizeof(hash));
+ memcpy(&trace_queue->trace_buffer[tmp].data[sizeof(hash)], &id,
+ sizeof(id));
+ memcpy(&trace_queue->trace_buffer[tmp].data[sizeof(hash)+sizeof(id)],
+ data, len);
+ memset(&trace_queue->trace_buffer[tmp].data[len+sizeof(hash)+ sizeof(id)],
+ 0, EFFECTIVE_SLOT_SIZE-len-(sizeof(hash)+sizeof(id)));
+ trace_queue->trace_buffer[tmp].metadata.write_complete = 1;
+ return 0;
+}
+
+/* Read trace data from buffer.
+ * @trace_queue : pointer to the trace queue.
+ * @data : pointer to DebugEntry variable
+ * into which data gets read.
+ * return : pointer to address of DebugEntry variable
+ * into which data gets read.
+ * NULL in case of error.
+ */
+struct DebugEntry* read_trace_from_buffer(struct DebugBuffer *trace_queue,
+ struct DebugEntry *data)
+{
+ /* Exit early if tracing is disabled */
+ if (!trace_queue->enabled)
+ return NULL;
+
+ if (!trace_queue || !data )
+ return NULL;
+
+ /* check for empty buffer OR incomplete writes*/
+ if (trace_queue->first == trace_queue->last ||
+ !trace_queue->trace_buffer[trace_queue->first].
+ metadata.write_complete)
+ return NULL;
+
+ memcpy(data, &trace_queue->trace_buffer[trace_queue->first],
+ sizeof(struct DebugEntry));
+ trace_queue->first = INCREMENT_INDEX(trace_queue, first);
+
+ return data;
+}
===================================================================
@@ -0,0 +1,56 @@
+/*
+ * Trace buffer implementation for QEMU.
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Author:
+ * Prerna <prerna@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+
+#ifndef __TRACE_BUFFER_H__
+#define __TRACE_BUFFER_H__
+#include<stdint.h>
+
+#include"qemu-common.h"
+
+#define BUFFER_SIZE 128 /* Number of debug slots */
+#define SLOT_SIZE 40 /* size of buffer slot in bytes */
+#define EFFECTIVE_SLOT_SIZE SLOT_SIZE-9
+
+struct DebugEntry{
+ char data[EFFECTIVE_SLOT_SIZE];
+ uint64_t timestamp;
+ struct {
+ unsigned write_complete :1;
+ unsigned reserved :7;
+ } metadata;
+};
+
+struct DebugBuffer {
+ uint8_t enabled; /* flag to test if buffer is enabled */
+ /* 1 for enabled, 0 for disabled */
+ uint16_t buf_size; /* Size of buffer */
+ uint16_t first; /* Index to first entry of queue
+ * from where first 'read' occurs.
+ */
+ uint16_t last; /* Index to last entry of queue
+ * at which next 'write' must occur.
+ */
+ struct DebugEntry trace_buffer[BUFFER_SIZE];
+};
+
+struct DebugBuffer qemu_buf;
+
+/* Trace Buffer manipulation functions */
+void initialize_buffer (struct DebugBuffer *head);
+int write_trace_to_buffer(struct DebugBuffer *trace_queue,
+ uint32_t hash, uint8_t id, const void *data,
+ size_t len/*, EVENT_TYPE etype*/);
+struct DebugEntry * read_trace_from_buffer(struct DebugBuffer *trace_queue,
+ struct DebugEntry *data);
+#endif /* __TRACE_BUFFER_H__ */
===================================================================
@@ -114,6 +114,10 @@ show migration status
show balloon information
@item info qtree
show device tree
+@item info trace
+show contents of trace buffer
+@item info tracepoint
+show status of all tracepoints
@end table
ETEXI
@@ -158,7 +162,7 @@ ETEXI
STEXI
@item change @var{device} @var{setting}
-@findex change
+@findex :change
Change the configuration of a device.
@@ -235,9 +239,41 @@ STEXI
@item log @var{item1}[,...]
@findex log
Activate logging of the specified items to @file{/tmp/qemu.log}.
+#ifdef CONFIG_QEMU_TRACE
ETEXI
{
+ .name = "trace",
+ .args_type = "option:s?",
+ .params = "[on|off]",
+ .help = "activate logging of the specified items ",
+ .mhandler.cmd = do_trace,
+ },
+
+STEXI
+@item trace [on|off]
+@findex trace
+If called with option on, it enables tracing.
+If called with option off, tracing is disabled.
+#endif
+ETEXI
+
+ {
+ .name = "tracepoint",
+ .args_type = "name:s,option:s",
+ .params = "name on|off",
+ .help = "activate / deactivate tracepoint ",
+ .mhandler.cmd = do_tracepoint_status,
+ },
+
+STEXI
+@item tracepoint @var [on|off]
+@findex tracepoint
+If called with option 'on', it enables tracepoint @var.
+If called with option 'off', tracepoint @var is disabled.
+ETEXI
+
+ {
.name = "savevm",
.args_type = "name:s?",
.params = "[tag|id]",
===================================================================
@@ -166,6 +166,10 @@ int main(int argc, char **argv)
//#define DEBUG_NET
//#define DEBUG_SLIRP
+#ifdef CONFIG_QEMU_TRACE
+#include "trace-entries.h"
+#endif
+
#define DEFAULT_RAM_SIZE 128
#define MAX_VIRTIO_CONSOLES 1
@@ -3653,6 +3657,11 @@ int main(int argc, char **argv, char **e
drive_add(NULL, SD_ALIAS);
}
+#ifdef CONFIG_QEMU_TRACE
+ init_tracepoint_tbl();
+ init_tracepoints();
+#endif
+
/* open the virtual block devices */
if (snapshot)
qemu_opts_foreach(&qemu_drive_opts, drive_enable_snapshot, NULL, 0);
===================================================================
@@ -283,6 +283,7 @@ bsd="no"
linux="no"
solaris="no"
profiler="no"
+trace="no"
cocoa="no"
softmmu="yes"
linux_user="no"
@@ -575,6 +576,10 @@ for opt do
;;
--enable-profiler) profiler="yes"
;;
+ --enable-trace) trace="yes"
+ ;;
+ --disable-trace) trace="no"
+ ;;
--enable-cocoa)
cocoa="yes" ;
sdl="no" ;
@@ -2003,6 +2008,7 @@ echo "gprof enabled $gprof"
echo "sparse enabled $sparse"
echo "strip binaries $strip_opt"
echo "profiler $profiler"
+echo "trace $trace"
echo "static build $static"
echo "-Werror enabled $werror"
if test "$darwin" = "yes" ; then
@@ -2121,6 +2127,9 @@ fi
if test $profiler = "yes" ; then
echo "CONFIG_PROFILER=y" >> $config_host_mak
fi
+if test $trace = "yes" ; then
+ echo "CONFIG_QEMU_TRACE=y" >> $config_host_mak
+fi
if test "$slirp" = "yes" ; then
echo "CONFIG_SLIRP=y" >> $config_host_mak
QEMU_CFLAGS="-I\$(SRC_PATH)/slirp $QEMU_CFLAGS"
===================================================================
@@ -162,6 +162,10 @@ endif #CONFIG_BSD_USER
ifdef CONFIG_SOFTMMU
obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o
+#add option for trace-buffer to be integrated
+ifdef CONFIG_QEMU_TRACE
+obj-y += $(trace-obj-y)
+endif
# virtio has to be here due to weird dependency between PCI and virtio-net.
# need to fix this properly
obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
===================================================================
@@ -0,0 +1,95 @@
+/*
+ * Tracepoint implementation for QEMU.
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Author:
+ * Prerna <prerna@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef __TRACEPOINT_H__
+#define __TRACEPOINT_H__
+#include<stdarg.h>
+
+#include "qemu-queue.h"
+#include "trace-buffer.h"
+#include "monitor.h"
+#include "qdict.h"
+
+struct tracepoint {
+ char *name; /* Tracepoint name */
+ uint8_t trace_id; /* numerical ID */
+ uint8_t state; /* State. */
+ void (*print_fn)(Monitor *mon, void *ptr);
+ /* print function */
+} __attribute__((aligned(32)));
+
+#define DECLARE_TRACE(name, tproto, tstruct) \
+ struct __trace_struct_##name { \
+ tstruct \
+ }; \
+ extern void trace_##name(tproto); \
+ extern void __trace_print_##name(Monitor *mon, void *data);
+
+#define DEFINE_TRACE(name, tproto, tassign, tprint) \
+ void trace_##name(tproto) \
+ { \
+ unsigned int hash; \
+ char tpname[] = __stringify(name); \
+ struct tracepoint *tp; \
+ struct __trace_struct_##name var, *entry; \
+ \
+ hash = tdb_hash(tpname); \
+ tp = find_tracepoint_by_name(tpname); \
+ if (tp == NULL || !tp->state) \
+ return; \
+ \
+ entry = &var; \
+ tassign \
+ \
+ write_trace_to_buffer(&qemu_buf, hash, tp->trace_id, \
+ entry, sizeof(struct __trace_struct_##name)); \
+ } \
+ \
+ void __trace_print_##name(Monitor *mon, void *data) \
+ { \
+ struct __trace_struct_##name *entry; \
+ \
+ if(!entry) \
+ return; \
+ \
+ entry = (struct __trace_struct_##name *)data; \
+ monitor_printf(mon,tprint); \
+ return; \
+ }
+
+#define INIT_TRACE(name) \
+ register_tracepoint(__stringify_1(name), __trace_print_##name)
+
+#define DO_TRACE(name, args...) \
+ trace_##name(args);
+
+#define TP_PROTO(proto...) proto
+#define TP_ARGS(args...) args
+#define __field(type, item) type item
+#define TP_STRUCT__entry(args...) args
+#define TP_fast_assign(args...) args
+
+#define __entry entry
+#define __stringify_1(x...) #x
+#define __stringify(x...) __stringify_1(x)
+#define TP_printk(fmt, args...) fmt, args
+
+
+void init_tracepoint_tbl(void);
+extern struct tracepoint* register_tracepoint(const char *name,
+ void *print_func);
+extern struct tracepoint* find_tracepoint_by_name(const char *name);
+extern struct tracepoint* find_tracepoint_by_id(uint32_t hash, uint8_t id);
+extern void print_trace(struct DebugEntry *ptr, Monitor *mon);
+void do_info_tracepoint(Monitor *mon);
+#endif /* __TRACEPOINT_H__ */
===================================================================
@@ -0,0 +1,216 @@
+/*
+ * Tracepoint implementation for QEMU.
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Author:
+ * Prerna <prerna@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "tracepoint.h"
+
+#define TRACEPOINT_HASH_BITS 6
+#define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
+static QLIST_HEAD(tracepoint_head, tracepoint_lib)
+ tracepoint_table[TRACEPOINT_TABLE_SIZE];
+
+/* In essence, the structure becomes :
+ * struct tracepoint_lib {
+ * struct tracepoint {
+ * char *name;
+ * uint8_t trace_id;
+ * uint8_t state;
+ * void (*print_fn)(Monitor *mon, void *ptr);
+ * }entry;
+ * struct {
+ * struct tracepoint_lib *le_next;
+ * struct tracepoint_lib **le_prev;
+ * }list_ptr;
+ *
+ */
+struct tracepoint_lib {
+ struct tracepoint entry;
+ QLIST_ENTRY(tracepoint_lib) list_ptr;
+};
+
+/*
+ * Initialize tracepoint table
+ *
+ */
+void init_tracepoint_tbl(void)
+{
+ int i=0;
+ for (i=0; i< TRACEPOINT_TABLE_SIZE; i++)
+ QLIST_INIT(&tracepoint_table[i]);
+}
+
+/*
+ * Register a given tracepoint in the global library
+ * @name : tracepoint name string
+ * @print_func : ptr to function that eventually prints logged traces.
+ * return : struct tracepoint * , NULL for error.
+ *
+ */
+struct tracepoint* register_tracepoint(const char *name, void *print_func)
+{
+ unsigned int hash;
+ uint8_t idx=0;
+ struct tracepoint_head *head;
+ struct tracepoint_lib *e, *new_entry, *prev;
+
+ if (!name || !print_func)
+ return NULL;
+
+ hash = tdb_hash(name);
+ head = &tracepoint_table[hash % TRACEPOINT_TABLE_SIZE];
+
+ e = find_tracepoint_by_name(name);
+ if (e)
+ return e;
+
+ new_entry = (struct tracepoint_lib*)
+ qemu_malloc(sizeof(struct tracepoint_lib));
+
+ if (!new_entry)
+ return NULL; /* No memory */
+
+ new_entry->entry.name = (char*)qemu_malloc(strlen(name)+1);
+ if(!new_entry->entry.name)
+ return NULL;
+
+ strncpy(new_entry->entry.name, name, strlen(name)+1);
+ new_entry->entry.trace_id = 0; /* Trace ID */
+ new_entry->entry.state = 0; /* inactive */
+ new_entry->entry.print_fn = print_func;
+ new_entry->list_ptr.le_next = NULL;
+ new_entry->list_ptr.le_prev = NULL;
+
+ /* Add entry to tracepoint lib */
+ if (!QLIST_EMPTY(head)) {
+ prev = QLIST_FIRST(head);
+ QLIST_FOREACH(e, head, list_ptr) {
+ idx++;
+ prev = e;
+ if (!strcmp(name, e->entry.name)) {
+ qemu_free(new_entry->entry.name);
+ qemu_free(new_entry);
+ return NULL; /* Already exists */
+ }
+ }
+ new_entry->entry.trace_id = idx; /* Trace ID */
+ QLIST_INSERT_AFTER(prev, new_entry, list_ptr);
+ }
+ else
+ QLIST_INSERT_HEAD(head, new_entry, list_ptr);
+
+ return &(new_entry->entry);
+}
+
+/*
+ * Return tracepoint* for a given name
+ * @name : name string
+ * return : struct tracepoint* in case of a successful match
+ * NULL otherwise.
+ *
+ */
+struct tracepoint* find_tracepoint_by_name(const char *name)
+{
+ unsigned int hash;
+ struct tracepoint_head *head;
+ struct tracepoint_lib *e;
+
+ if(name == NULL)
+ return NULL;
+
+ hash = tdb_hash(name);
+ head = &tracepoint_table[hash % TRACEPOINT_TABLE_SIZE];
+
+ if(QLIST_EMPTY(head))
+ return NULL;
+
+ QLIST_FOREACH(e, head, list_ptr) {
+ if(!strcmp(name, e->entry.name))
+ return &(e->entry);
+ }
+
+ return NULL;
+}
+
+/*
+ * Return struct tracepoint entry corresponding to
+ * a given hash and id.
+ *
+ * @hash: hash value of tracepoint name
+ * @id : trace_id of the tracepoint
+ *
+ */
+struct tracepoint* find_tracepoint_by_id(unsigned int hash, uint8_t id)
+{
+ struct tracepoint_head *head;
+ struct tracepoint_lib *e;
+
+ head = &tracepoint_table[hash % TRACEPOINT_TABLE_SIZE];
+
+ if(QLIST_EMPTY(head)) /* List empty */
+ return NULL;
+
+ QLIST_FOREACH(e, head, list_ptr) {
+ if(e->entry.trace_id == id)
+ return &(e->entry);
+ }
+
+ return NULL; /* Not found */
+}
+
+/*
+ * Display data logged
+ *
+ * @ptr : pointer to the DebugEntry in the trace buffer
+ * @mon : pointer to Monitor
+ *
+ */
+void print_trace(struct DebugEntry *ptr, Monitor *mon)
+{
+ unsigned int hash;
+ uint8_t id;
+ struct tracepoint *tp;
+
+ if(ptr == NULL)
+ return;
+
+ memcpy(&hash, ptr->data, sizeof(hash));
+ id = ptr->data[sizeof(hash)];
+
+ tp = find_tracepoint_by_id(hash, id);
+ if (tp == NULL) {
+ monitor_printf(mon, "Not found : hash %u, id %u\n",hash, id);
+ return;
+ }
+
+// monitor_printf(mon, "Found %s : hash %u, id %u\n",tp->name, hash, id);
+ (tp->print_fn)(mon, (void*)&ptr->data[sizeof(hash)+sizeof(id)]);
+ return;
+}
+
+/*
+ * Print all available tracepoints with their status.
+ * (Called from monitor)
+ */
+void do_info_tracepoint(Monitor *mon)
+{
+ int i;
+ struct tracepoint_head *head;
+ struct tracepoint_lib *e;
+
+ for (i=0; i< TRACEPOINT_TABLE_SIZE; i++) {
+ head = &tracepoint_table[i];
+ if(!QLIST_EMPTY(head)) {
+ QLIST_FOREACH(e, head, list_ptr)
+ monitor_printf(mon, "%s %d\n", e->entry.name, e->entry.state);
+ }
+ }
+}
===================================================================
@@ -0,0 +1,33 @@
+/*
+ * Tracepoint declarations for QEMU.
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Author:
+ * Prerna <prerna@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef __TRACE_ENTRIES_H__
+#define __TRACE_ENTRIES_H__
+
+#include "tracepoint.h"
+
+void init_tracepoints(void);
+
+/*
+ * Add DECLARE_TRACE macros here.
+ *
+ * DECLARE_TRACE( name,
+ * TP_PROTO( type1 var1, type2 var2..),
+ * TP_STRUCT__entry(
+ * __field(type1, var1);
+ * __field(type2, var2);...
+ * ),
+ * )
+ */
+
+#endif /*__TRACE_ENTRIES_H__ */
===================================================================
@@ -0,0 +1,40 @@
+/*
+ * Tracepoint declaration(s) for QEMU.
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Author:
+ * Prerna <prerna@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+#include "trace-entries.h"
+/*
+ * Initialize tracepoints
+ * Add INIT_TRACE() macro for each tracepoint you declare,
+ * inside this function.
+ *
+ */
+void init_tracepoints(void)
+{
+// INIT_TRACE(foo);
+
+ return;
+}
+
+/*
+ * Add a DEFINE_TRACE() macro for each tracepoint you declare.
+ *
+ * DEFINE_TRACE( name,
+ * TP_PROTO( type1 var1, type2 var2..),
+ * TP_fast_assign(
+ * __entry->var1 = arg1;
+ * __entry->var2 = arg2;...
+ * ),
+ * TP_printk("....", __entry->var1, __entry->var2) // No semicolon at end
+ * )
+ *
+ */
+
===================================================================
@@ -5,6 +5,10 @@ qobject-obj-y += qjson.o json-lexer.o js
qobject-obj-y += qerror.o
#######################################################################
+# Trace Object
+trace-obj-y = trace-buffer.o tracepoint.o trace-entries.o $(SRC_PATH)/qdict.h
+
+#######################################################################
# block-obj-y is code used by both qemu system emulation and qemu-img
block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o
===================================================================
@@ -1,6 +1,6 @@
# Makefile for QEMU.
-GENERATED_HEADERS = config-host.h
+GENERATED_HEADERS = config-host.h trace-entries.h
ifneq ($(wildcard config-host.mak),)
# Put the all: rule here so that config-host.mak can contain dependencies.
@@ -130,16 +130,18 @@ bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS
iov.o: iov.c iov.h
+#tracepoint.o: tracepoint.h tracepoint.c $(SRC_PATH)/qdict.h
+
######################################################################
qemu-img.o: qemu-img-cmds.h
qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS)
-qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y)
+qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y) $(trace-obj-y)
-qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y)
+qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y) $(trace-obj-y)
-qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y)
+qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y) $(trace-obj-y)
qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $@")