Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/samples/ftrace/sample-trace-array.c
26285 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
#include <linux/module.h>
3
#include <linux/kthread.h>
4
#include <linux/trace.h>
5
#include <linux/trace_events.h>
6
#include <linux/timer.h>
7
#include <linux/err.h>
8
#include <linux/jiffies.h>
9
#include <linux/workqueue.h>
10
11
/*
12
* Any file that uses trace points, must include the header.
13
* But only one file, must include the header by defining
14
* CREATE_TRACE_POINTS first. This will make the C code that
15
* creates the handles for the trace points.
16
*/
17
#define CREATE_TRACE_POINTS
18
#include "sample-trace-array.h"
19
20
struct trace_array *tr;
21
static void mytimer_handler(struct timer_list *unused);
22
static struct task_struct *simple_tsk;
23
24
static void trace_work_fn(struct work_struct *work)
25
{
26
/*
27
* Disable tracing for event "sample_event".
28
*/
29
trace_array_set_clr_event(tr, "sample-subsystem", "sample_event",
30
false);
31
}
32
static DECLARE_WORK(trace_work, trace_work_fn);
33
34
/*
35
* mytimer: Timer setup to disable tracing for event "sample_event". This
36
* timer is only for the purposes of the sample module to demonstrate access of
37
* Ftrace instances from within kernel.
38
*/
39
static DEFINE_TIMER(mytimer, mytimer_handler);
40
41
static void mytimer_handler(struct timer_list *unused)
42
{
43
schedule_work(&trace_work);
44
}
45
46
static void simple_thread_func(int count)
47
{
48
set_current_state(TASK_INTERRUPTIBLE);
49
schedule_timeout(HZ);
50
51
/*
52
* Printing count value using trace_array_printk() - trace_printk()
53
* equivalent for the instance buffers.
54
*/
55
trace_array_printk(tr, _THIS_IP_, "trace_array_printk: count=%d\n",
56
count);
57
/*
58
* Tracepoint for event "sample_event". This will print the
59
* current value of count and current jiffies.
60
*/
61
trace_sample_event(count, jiffies);
62
}
63
64
static int simple_thread(void *arg)
65
{
66
int count = 0;
67
unsigned long delay = msecs_to_jiffies(5000);
68
69
/*
70
* Enable tracing for "sample_event".
71
*/
72
trace_array_set_clr_event(tr, "sample-subsystem", "sample_event", true);
73
74
/*
75
* Adding timer - mytimer. This timer will disable tracing after
76
* delay seconds.
77
*
78
*/
79
add_timer(&mytimer);
80
mod_timer(&mytimer, jiffies+delay);
81
82
while (!kthread_should_stop())
83
simple_thread_func(count++);
84
85
timer_delete(&mytimer);
86
cancel_work_sync(&trace_work);
87
88
/*
89
* trace_array_put() decrements the reference counter associated with
90
* the trace array - "tr". We are done using the trace array, hence
91
* decrement the reference counter so that it can be destroyed using
92
* trace_array_destroy().
93
*/
94
trace_array_put(tr);
95
96
return 0;
97
}
98
99
static int __init sample_trace_array_init(void)
100
{
101
/*
102
* Return a pointer to the trace array with name "sample-instance" if it
103
* exists, else create a new trace array.
104
*
105
* NOTE: This function increments the reference counter
106
* associated with the trace array - "tr".
107
*/
108
tr = trace_array_get_by_name("sample-instance", "sched,timer,kprobes");
109
110
if (!tr)
111
return -1;
112
/*
113
* If context specific per-cpu buffers havent already been allocated.
114
*/
115
trace_array_init_printk(tr);
116
117
simple_tsk = kthread_run(simple_thread, NULL, "sample-instance");
118
if (IS_ERR(simple_tsk)) {
119
trace_array_put(tr);
120
trace_array_destroy(tr);
121
return -1;
122
}
123
124
return 0;
125
}
126
127
static void __exit sample_trace_array_exit(void)
128
{
129
kthread_stop(simple_tsk);
130
131
/*
132
* We are unloading our module and no longer require the trace array.
133
* Remove/destroy "tr" using trace_array_destroy()
134
*/
135
trace_array_destroy(tr);
136
}
137
138
module_init(sample_trace_array_init);
139
module_exit(sample_trace_array_exit);
140
141
MODULE_AUTHOR("Divya Indi");
142
MODULE_DESCRIPTION("Sample module for kernel access to Ftrace instances");
143
MODULE_LICENSE("GPL");
144
145