1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM timer
3
4#if !defined(_TRACE_TIMER_H) || defined(TRACE_HEADER_MULTI_READ)
5#define _TRACE_TIMER_H
6
7#include <linux/tracepoint.h>
8#include <linux/hrtimer.h>
9#include <linux/timer.h>
10
11DECLARE_EVENT_CLASS(timer_class,
12
13	TP_PROTO(struct timer_list *timer),
14
15	TP_ARGS(timer),
16
17	TP_STRUCT__entry(
18		__field( void *,	timer	)
19	),
20
21	TP_fast_assign(
22		__entry->timer	= timer;
23	),
24
25	TP_printk("timer=%p", __entry->timer)
26);
27
28/**
29 * timer_init - called when the timer is initialized
30 * @timer:	pointer to struct timer_list
31 */
32DEFINE_EVENT(timer_class, timer_init,
33
34	TP_PROTO(struct timer_list *timer),
35
36	TP_ARGS(timer)
37);
38
39/**
40 * timer_start - called when the timer is started
41 * @timer:	pointer to struct timer_list
42 * @expires:	the timers expiry time
43 */
44TRACE_EVENT(timer_start,
45
46	TP_PROTO(struct timer_list *timer,
47		unsigned long expires,
48		unsigned int flags),
49
50	TP_ARGS(timer, expires, flags),
51
52	TP_STRUCT__entry(
53		__field( void *,	timer		)
54		__field( void *,	function	)
55		__field( unsigned long,	expires		)
56		__field( unsigned long,	now		)
57		__field( unsigned int,	flags		)
58	),
59
60	TP_fast_assign(
61		__entry->timer		= timer;
62		__entry->function	= timer->function;
63		__entry->expires	= expires;
64		__entry->now		= jiffies;
65		__entry->flags		= flags;
66	),
67
68	TP_printk("timer=%p function=%pf expires=%lu [timeout=%ld] flags=0x%08x",
69		  __entry->timer, __entry->function, __entry->expires,
70		  (long)__entry->expires - __entry->now, __entry->flags)
71);
72
73/**
74 * timer_expire_entry - called immediately before the timer callback
75 * @timer:	pointer to struct timer_list
76 *
77 * Allows to determine the timer latency.
78 */
79TRACE_EVENT(timer_expire_entry,
80
81	TP_PROTO(struct timer_list *timer),
82
83	TP_ARGS(timer),
84
85	TP_STRUCT__entry(
86		__field( void *,	timer	)
87		__field( unsigned long,	now	)
88		__field( void *,	function)
89	),
90
91	TP_fast_assign(
92		__entry->timer		= timer;
93		__entry->now		= jiffies;
94		__entry->function	= timer->function;
95	),
96
97	TP_printk("timer=%p function=%pf now=%lu", __entry->timer, __entry->function,__entry->now)
98);
99
100/**
101 * timer_expire_exit - called immediately after the timer callback returns
102 * @timer:	pointer to struct timer_list
103 *
104 * When used in combination with the timer_expire_entry tracepoint we can
105 * determine the runtime of the timer callback function.
106 *
107 * NOTE: Do NOT derefernce timer in TP_fast_assign. The pointer might
108 * be invalid. We solely track the pointer.
109 */
110DEFINE_EVENT(timer_class, timer_expire_exit,
111
112	TP_PROTO(struct timer_list *timer),
113
114	TP_ARGS(timer)
115);
116
117/**
118 * timer_cancel - called when the timer is canceled
119 * @timer:	pointer to struct timer_list
120 */
121DEFINE_EVENT(timer_class, timer_cancel,
122
123	TP_PROTO(struct timer_list *timer),
124
125	TP_ARGS(timer)
126);
127
128/**
129 * hrtimer_init - called when the hrtimer is initialized
130 * @hrtimer:	pointer to struct hrtimer
131 * @clockid:	the hrtimers clock
132 * @mode:	the hrtimers mode
133 */
134TRACE_EVENT(hrtimer_init,
135
136	TP_PROTO(struct hrtimer *hrtimer, clockid_t clockid,
137		 enum hrtimer_mode mode),
138
139	TP_ARGS(hrtimer, clockid, mode),
140
141	TP_STRUCT__entry(
142		__field( void *,		hrtimer		)
143		__field( clockid_t,		clockid		)
144		__field( enum hrtimer_mode,	mode		)
145	),
146
147	TP_fast_assign(
148		__entry->hrtimer	= hrtimer;
149		__entry->clockid	= clockid;
150		__entry->mode		= mode;
151	),
152
153	TP_printk("hrtimer=%p clockid=%s mode=%s", __entry->hrtimer,
154		  __entry->clockid == CLOCK_REALTIME ?
155			"CLOCK_REALTIME" : "CLOCK_MONOTONIC",
156		  __entry->mode == HRTIMER_MODE_ABS ?
157			"HRTIMER_MODE_ABS" : "HRTIMER_MODE_REL")
158);
159
160/**
161 * hrtimer_start - called when the hrtimer is started
162 * @hrtimer: pointer to struct hrtimer
163 */
164TRACE_EVENT(hrtimer_start,
165
166	TP_PROTO(struct hrtimer *hrtimer),
167
168	TP_ARGS(hrtimer),
169
170	TP_STRUCT__entry(
171		__field( void *,	hrtimer		)
172		__field( void *,	function	)
173		__field( s64,		expires		)
174		__field( s64,		softexpires	)
175	),
176
177	TP_fast_assign(
178		__entry->hrtimer	= hrtimer;
179		__entry->function	= hrtimer->function;
180		__entry->expires	= hrtimer_get_expires(hrtimer).tv64;
181		__entry->softexpires	= hrtimer_get_softexpires(hrtimer).tv64;
182	),
183
184	TP_printk("hrtimer=%p function=%pf expires=%llu softexpires=%llu",
185		  __entry->hrtimer, __entry->function,
186		  (unsigned long long)ktime_to_ns((ktime_t) {
187				  .tv64 = __entry->expires }),
188		  (unsigned long long)ktime_to_ns((ktime_t) {
189				  .tv64 = __entry->softexpires }))
190);
191
192/**
193 * hrtimer_expire_entry - called immediately before the hrtimer callback
194 * @hrtimer:	pointer to struct hrtimer
195 * @now:	pointer to variable which contains current time of the
196 *		timers base.
197 *
198 * Allows to determine the timer latency.
199 */
200TRACE_EVENT(hrtimer_expire_entry,
201
202	TP_PROTO(struct hrtimer *hrtimer, ktime_t *now),
203
204	TP_ARGS(hrtimer, now),
205
206	TP_STRUCT__entry(
207		__field( void *,	hrtimer	)
208		__field( s64,		now	)
209		__field( void *,	function)
210	),
211
212	TP_fast_assign(
213		__entry->hrtimer	= hrtimer;
214		__entry->now		= now->tv64;
215		__entry->function	= hrtimer->function;
216	),
217
218	TP_printk("hrtimer=%p function=%pf now=%llu", __entry->hrtimer, __entry->function,
219		  (unsigned long long)ktime_to_ns((ktime_t) { .tv64 = __entry->now }))
220 );
221
222DECLARE_EVENT_CLASS(hrtimer_class,
223
224	TP_PROTO(struct hrtimer *hrtimer),
225
226	TP_ARGS(hrtimer),
227
228	TP_STRUCT__entry(
229		__field( void *,	hrtimer	)
230	),
231
232	TP_fast_assign(
233		__entry->hrtimer	= hrtimer;
234	),
235
236	TP_printk("hrtimer=%p", __entry->hrtimer)
237);
238
239/**
240 * hrtimer_expire_exit - called immediately after the hrtimer callback returns
241 * @hrtimer:	pointer to struct hrtimer
242 *
243 * When used in combination with the hrtimer_expire_entry tracepoint we can
244 * determine the runtime of the callback function.
245 */
246DEFINE_EVENT(hrtimer_class, hrtimer_expire_exit,
247
248	TP_PROTO(struct hrtimer *hrtimer),
249
250	TP_ARGS(hrtimer)
251);
252
253/**
254 * hrtimer_cancel - called when the hrtimer is canceled
255 * @hrtimer:	pointer to struct hrtimer
256 */
257DEFINE_EVENT(hrtimer_class, hrtimer_cancel,
258
259	TP_PROTO(struct hrtimer *hrtimer),
260
261	TP_ARGS(hrtimer)
262);
263
264/**
265 * itimer_state - called when itimer is started or canceled
266 * @which:	name of the interval timer
267 * @value:	the itimers value, itimer is canceled if value->it_value is
268 *		zero, otherwise it is started
269 * @expires:	the itimers expiry time
270 */
271TRACE_EVENT(itimer_state,
272
273	TP_PROTO(int which, const struct itimerval *const value,
274		 cputime_t expires),
275
276	TP_ARGS(which, value, expires),
277
278	TP_STRUCT__entry(
279		__field(	int,		which		)
280		__field(	cputime_t,	expires		)
281		__field(	long,		value_sec	)
282		__field(	long,		value_usec	)
283		__field(	long,		interval_sec	)
284		__field(	long,		interval_usec	)
285	),
286
287	TP_fast_assign(
288		__entry->which		= which;
289		__entry->expires	= expires;
290		__entry->value_sec	= value->it_value.tv_sec;
291		__entry->value_usec	= value->it_value.tv_usec;
292		__entry->interval_sec	= value->it_interval.tv_sec;
293		__entry->interval_usec	= value->it_interval.tv_usec;
294	),
295
296	TP_printk("which=%d expires=%llu it_value=%ld.%ld it_interval=%ld.%ld",
297		  __entry->which, (unsigned long long)__entry->expires,
298		  __entry->value_sec, __entry->value_usec,
299		  __entry->interval_sec, __entry->interval_usec)
300);
301
302/**
303 * itimer_expire - called when itimer expires
304 * @which:	type of the interval timer
305 * @pid:	pid of the process which owns the timer
306 * @now:	current time, used to calculate the latency of itimer
307 */
308TRACE_EVENT(itimer_expire,
309
310	TP_PROTO(int which, struct pid *pid, cputime_t now),
311
312	TP_ARGS(which, pid, now),
313
314	TP_STRUCT__entry(
315		__field( int ,		which	)
316		__field( pid_t,		pid	)
317		__field( cputime_t,	now	)
318	),
319
320	TP_fast_assign(
321		__entry->which	= which;
322		__entry->now	= now;
323		__entry->pid	= pid_nr(pid);
324	),
325
326	TP_printk("which=%d pid=%d now=%llu", __entry->which,
327		  (int) __entry->pid, (unsigned long long)__entry->now)
328);
329
330#ifdef CONFIG_NO_HZ_COMMON
331TRACE_EVENT(tick_stop,
332
333	TP_PROTO(int success, char *error_msg),
334
335	TP_ARGS(success, error_msg),
336
337	TP_STRUCT__entry(
338		__field( int ,		success	)
339		__string( msg, 		error_msg )
340	),
341
342	TP_fast_assign(
343		__entry->success	= success;
344		__assign_str(msg, error_msg);
345	),
346
347	TP_printk("success=%s msg=%s",  __entry->success ? "yes" : "no", __get_str(msg))
348);
349#endif
350
351#endif /*  _TRACE_TIMER_H */
352
353/* This part must be outside protection */
354#include <trace/define_trace.h>
355