forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tracing/events: add trace-events-sample
This patch adds a sample to the samples directory on how to create and use TRACE_EVENT trace points. Signed-off-by: Steven Rostedt <[email protected]>
- Loading branch information
Showing
5 changed files
with
196 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
# Makefile for Linux samples code | ||
|
||
obj-$(CONFIG_SAMPLES) += markers/ kobject/ kprobes/ tracepoints/ | ||
obj-$(CONFIG_SAMPLES) += markers/ kobject/ kprobes/ tracepoints/ trace_events/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# builds the trace events example kernel modules; | ||
# then to use one (as root): insmod <module_name.ko> | ||
|
||
PWD := $(shell pwd) | ||
|
||
CFLAGS_trace-events-sample.o := -I$(PWD)/samples/trace_events/ | ||
|
||
obj-$(CONFIG_SAMPLE_TRACE_EVENTS) += trace-events-sample.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#include <linux/module.h> | ||
#include <linux/kthread.h> | ||
|
||
/* | ||
* Any file that uses trace points, must include the header. | ||
* But only one file, must include the header by defining | ||
* CREATE_TRACE_POINTS first. This will make the C code that | ||
* creates the handles for the trace points. | ||
*/ | ||
#define CREATE_TRACE_POINTS | ||
#include "trace-events-sample.h" | ||
|
||
|
||
static void simple_thread_func(int cnt) | ||
{ | ||
set_current_state(TASK_INTERRUPTIBLE); | ||
schedule_timeout(HZ); | ||
trace_foo_bar("hello", cnt); | ||
|
||
if (!(cnt % 10)) | ||
/* It is really important that I say "hi!" */ | ||
printk(KERN_EMERG "hi!\n"); | ||
} | ||
|
||
static int simple_thread(void *arg) | ||
{ | ||
int cnt = 0; | ||
|
||
while (!kthread_should_stop()) | ||
simple_thread_func(cnt++); | ||
|
||
return 0; | ||
} | ||
|
||
static struct task_struct *simple_tsk; | ||
|
||
static int __init trace_event_init(void) | ||
{ | ||
simple_tsk = kthread_run(simple_thread, NULL, "event-sample"); | ||
if (IS_ERR(simple_tsk)) | ||
return -1; | ||
|
||
return 0; | ||
} | ||
|
||
static void __exit trace_event_exit(void) | ||
{ | ||
kthread_stop(simple_tsk); | ||
} | ||
|
||
module_init(trace_event_init); | ||
module_exit(trace_event_exit); | ||
|
||
MODULE_AUTHOR("Steven Rostedt"); | ||
MODULE_DESCRIPTION("trace-events-sample"); | ||
MODULE_LICENSE("GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
/* | ||
* Notice that this file is not protected like a normal header. | ||
* We also must allow for rereading of this file. The | ||
* | ||
* || defined(TRACE_HEADER_MULTI_READ) | ||
* | ||
* serves this purpose. | ||
*/ | ||
#if !defined(_TRACE_EVENT_SAMPLE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
#define _TRACE_EVENT_SAMPLE_H | ||
|
||
/* | ||
* All trace headers should include tracepoint.h, until we finally | ||
* make it into a standard header. | ||
*/ | ||
#include <linux/tracepoint.h> | ||
|
||
/* | ||
* If TRACE_SYSTEM is defined, that will be the directory created | ||
* in the ftrace directory under /debugfs/tracing/events/<system> | ||
* | ||
* The define_trace.h belowe will also look for a file name of | ||
* TRACE_SYSTEM.h where TRACE_SYSTEM is what is defined here. | ||
* | ||
* If you want a different system than file name, you can override | ||
* the header name by defining TRACE_INCLUDE_FILE | ||
* | ||
* If this file was called, goofy.h, then we would define: | ||
* | ||
* #define TRACE_INCLUDE_FILE goofy | ||
* | ||
*/ | ||
#undef TRACE_SYSTEM | ||
#define TRACE_SYSTEM trace-events-sample | ||
|
||
/* | ||
* The TRACE_EVENT macro is broken up into 5 parts. | ||
* | ||
* name: name of the trace point. This is also how to enable the tracepoint. | ||
* A function called trace_foo_bar() will be created. | ||
* | ||
* proto: the prototype of the function trace_foo_bar() | ||
* Here it is trace_foo_bar(char *foo, int bar). | ||
* | ||
* args: must match the arguments in the prototype. | ||
* Here it is simply "foo, bar". | ||
* | ||
* struct: This defines the way the data will be stored in the ring buffer. | ||
* There are currently two types of elements. __field and __array. | ||
* a __field is broken up into (type, name). Where type can be any | ||
* type but an array. | ||
* For an array. there are three fields. (type, name, size). The | ||
* type of elements in the array, the name of the field and the size | ||
* of the array. | ||
* | ||
* __array( char, foo, 10) is the same as saying char foo[10]. | ||
* | ||
* fast_assign: This is a C like function that is used to store the items | ||
* into the ring buffer. | ||
* | ||
* printk: This is a way to print out the data in pretty print. This is | ||
* useful if the system crashes and you are logging via a serial line, | ||
* the data can be printed to the console using this "printk" method. | ||
* | ||
* Note, that for both the assign and the printk, __entry is the handler | ||
* to the data structure in the ring buffer, and is defined by the | ||
* TP_STRUCT__entry. | ||
*/ | ||
TRACE_EVENT(foo_bar, | ||
|
||
TP_PROTO(char *foo, int bar), | ||
|
||
TP_ARGS(foo, bar), | ||
|
||
TP_STRUCT__entry( | ||
__array( char, foo, 10 ) | ||
__field( int, bar ) | ||
), | ||
|
||
TP_fast_assign( | ||
strncpy(__entry->foo, foo, 10); | ||
__entry->bar = bar; | ||
), | ||
|
||
TP_printk("foo %s %d", __entry->foo, __entry->bar) | ||
); | ||
#endif | ||
|
||
/***** NOTICE! The #if protection ends here. *****/ | ||
|
||
|
||
/* | ||
* There are several ways I could have done this. If I left out the | ||
* TRACE_INCLUDE_PATH, then it would default to the kernel source | ||
* include/trace/events directory. | ||
* | ||
* I could specify a path from the define_trace.h file back to this | ||
* file. | ||
* | ||
* #define TRACE_INCLUDE_PATH ../../samples/trace_events | ||
* | ||
* But I chose to simply make it use the current directory and then in | ||
* the Makefile I added: | ||
* | ||
* CFLAGS_trace-events-sample.o := -I$(PWD)/samples/trace_events/ | ||
* | ||
* This will make sure the current path is part of the include | ||
* structure for our file so that we can find it. | ||
* | ||
* I could have made only the top level directory the include: | ||
* | ||
* CFLAGS_trace-events-sample.o := -I$(PWD) | ||
* | ||
* And then let the path to this directory be the TRACE_INCLUDE_PATH: | ||
* | ||
* #define TRACE_INCLUDE_PATH samples/trace_events | ||
* | ||
* But then if something defines "samples" or "trace_events" then we | ||
* could risk that being converted too, and give us an unexpected | ||
* result. | ||
*/ | ||
#undef TRACE_INCLUDE_PATH | ||
#define TRACE_INCLUDE_PATH . | ||
#include <trace/define_trace.h> |