Skip to content

Commit

Permalink
trace: Add ftrace tracing backend
Browse files Browse the repository at this point in the history
This patch adds a ftrace tracing backend which sends trace event to
ftrace marker file. You can effectively compare qemu trace data and
kernel(especially, kvm.ko when using KVM) trace data.
The ftrace backend is restricted to Linux only.

To try out the ftrace backend:

 $ ./configure --trace-backend=ftrace
 $ make

if you use KVM, enable kvm events in ftrace:

 # sudo echo 1 > /sys/kernel/debug/tracing/events/kvm/enable

After running qemu by root user, you can get the trace:

 # cat /sys/kernel/debug/tracing/trace

Signed-off-by: Eiichi Tsukata <[email protected]>
Signed-off-by: Stefan Hajnoczi <[email protected]>
  • Loading branch information
Eiichi Tsukata authored and stefanhaRH committed May 3, 2013
1 parent b76ac80 commit 781e954
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 0 deletions.
8 changes: 8 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -4004,6 +4004,14 @@ if test "$trace_backend" = "dtrace"; then
echo "CONFIG_TRACE_SYSTEMTAP=y" >> $config_host_mak
fi
fi
if test "$trace_backend" = "ftrace"; then
if test "$linux" = "yes" ; then
echo "CONFIG_TRACE_FTRACE=y" >> $config_host_mak
trace_default=no
else
feature_not_found "ftrace(trace backend)"
fi
fi
echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
if test "$trace_default" = "yes"; then
echo "CONFIG_TRACE_DEFAULT=y" >> $config_host_mak
Expand Down
54 changes: 54 additions & 0 deletions scripts/tracetool/backend/ftrace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Ftrace built-in backend.
"""

__author__ = "Eiichi Tsukata <[email protected]>"
__copyright__ = "Copyright (C) 2013 Hitachi, Ltd."
__license__ = "GPL version 2 or (at your option) any later version"

__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"


from tracetool import out


PUBLIC = True


def c(events):
pass

def h(events):
out('#include "trace/ftrace.h"',
'#include "trace/control.h"',
'',
)

for e in events:
argnames = ", ".join(e.args.names())
if len(e.args) > 0:
argnames = ", " + argnames

out('static inline void trace_%(name)s(%(args)s)',
'{',
' char ftrace_buf[MAX_TRACE_STRLEN];',
' int unused __attribute__ ((unused));',
' int trlen;',
' bool _state = trace_event_get_state(%(event_id)s);',
' if (_state) {',
' 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 = e.name,
args = e.args,
event_id = "TRACE_" + e.name.upper(),
fmt = e.fmt.rstrip("\n"),
argnames = argnames,
)
1 change: 1 addition & 0 deletions trace/Makefile.objs
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,6 @@ endif
util-obj-$(CONFIG_TRACE_DEFAULT) += default.o
util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o
util-obj-$(CONFIG_TRACE_STDERR) += stderr.o
util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
util-obj-y += control.o
util-obj-y += generated-tracers.o
102 changes: 102 additions & 0 deletions trace/ftrace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Ftrace trace backend
*
* Copyright (C) 2013 Hitachi, Ltd.
* Created by Eiichi Tsukata <[email protected]>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*
*/

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include "trace.h"
#include "trace/control.h"

int trace_marker_fd;

static int find_debugfs(char *debugfs)
{
char type[100];
FILE *fp;

fp = fopen("/proc/mounts", "r");
if (fp == NULL) {
return 0;
}

while (fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
debugfs, type) == 2) {
if (strcmp(type, "debugfs") == 0) {
break;
}
}
fclose(fp);

if (strcmp(type, "debugfs") != 0) {
return 0;
}
return 1;
}

void trace_print_events(FILE *stream, fprintf_function stream_printf)
{
TraceEventID i;

for (i = 0; i < trace_event_count(); i++) {
TraceEvent *ev = trace_event_id(i);
stream_printf(stream, "%s [Event ID %u] : state %u\n",
trace_event_get_name(ev), i, trace_event_get_state_dynamic(ev));
}
}

void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state)
{
ev->dstate = state;
}

bool trace_backend_init(const char *events, const char *file)
{
char debugfs[PATH_MAX];
char path[PATH_MAX];
int debugfs_found;
int trace_fd = -1;

if (file) {
fprintf(stderr, "error: -trace file=...: "
"option not supported by the selected tracing backend\n");
return false;
}

debugfs_found = find_debugfs(debugfs);
if (debugfs_found) {
snprintf(path, PATH_MAX, "%s/tracing/tracing_on", debugfs);
trace_fd = open(path, O_WRONLY);
if (trace_fd < 0) {
perror("Could not open ftrace 'tracing_on' file");
return false;
} else {
if (write(trace_fd, "1", 1) < 0) {
perror("Could not write to 'tracing_on' file");
close(trace_fd);
return false;
}
close(trace_fd);
}
snprintf(path, PATH_MAX, "%s/tracing/trace_marker", debugfs);
trace_marker_fd = open(path, O_WRONLY);
if (trace_marker_fd < 0) {
perror("Could not open ftrace 'trace_marker' file");
return false;
}
} else {
fprintf(stderr, "debugfs is not mounted\n");
return false;
}

trace_backend_init_events(events);
return true;
}
10 changes: 10 additions & 0 deletions trace/ftrace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef TRACE_FTRACE_H
#define TRACE_FTRACE_H

#define MAX_TRACE_STRLEN 512
#define _STR(x) #x
#define STR(x) _STR(x)

extern int trace_marker_fd;

#endif /* ! TRACE_FTRACE_H */

0 comments on commit 781e954

Please sign in to comment.