]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2b022e3d XG |
2 | #undef TRACE_SYSTEM |
3 | #define TRACE_SYSTEM timer | |
4 | ||
5 | #if !defined(_TRACE_TIMER_H) || defined(TRACE_HEADER_MULTI_READ) | |
6 | #define _TRACE_TIMER_H | |
7 | ||
8 | #include <linux/tracepoint.h> | |
c6a2a177 | 9 | #include <linux/hrtimer.h> |
2b022e3d XG |
10 | #include <linux/timer.h> |
11 | ||
363d0f64 | 12 | DECLARE_EVENT_CLASS(timer_class, |
2b022e3d XG |
13 | |
14 | TP_PROTO(struct timer_list *timer), | |
15 | ||
16 | TP_ARGS(timer), | |
17 | ||
18 | TP_STRUCT__entry( | |
19 | __field( void *, timer ) | |
20 | ), | |
21 | ||
22 | TP_fast_assign( | |
23 | __entry->timer = timer; | |
24 | ), | |
25 | ||
434a83c3 | 26 | TP_printk("timer=%p", __entry->timer) |
2b022e3d XG |
27 | ); |
28 | ||
363d0f64 LZ |
29 | /** |
30 | * timer_init - called when the timer is initialized | |
31 | * @timer: pointer to struct timer_list | |
32 | */ | |
33 | DEFINE_EVENT(timer_class, timer_init, | |
34 | ||
35 | TP_PROTO(struct timer_list *timer), | |
36 | ||
37 | TP_ARGS(timer) | |
38 | ); | |
39 | ||
8a58a34b TG |
40 | #define decode_timer_flags(flags) \ |
41 | __print_flags(flags, "|", \ | |
42 | { TIMER_MIGRATING, "M" }, \ | |
43 | { TIMER_DEFERRABLE, "D" }, \ | |
44 | { TIMER_PINNED, "P" }, \ | |
45 | { TIMER_IRQSAFE, "I" }) | |
46 | ||
2b022e3d XG |
47 | /** |
48 | * timer_start - called when the timer is started | |
49 | * @timer: pointer to struct timer_list | |
50 | * @expires: the timers expiry time | |
51 | */ | |
52 | TRACE_EVENT(timer_start, | |
53 | ||
4e413e85 BJS |
54 | TP_PROTO(struct timer_list *timer, |
55 | unsigned long expires, | |
0eeda71b | 56 | unsigned int flags), |
2b022e3d | 57 | |
0eeda71b | 58 | TP_ARGS(timer, expires, flags), |
2b022e3d XG |
59 | |
60 | TP_STRUCT__entry( | |
61 | __field( void *, timer ) | |
62 | __field( void *, function ) | |
63 | __field( unsigned long, expires ) | |
64 | __field( unsigned long, now ) | |
0eeda71b | 65 | __field( unsigned int, flags ) |
2b022e3d XG |
66 | ), |
67 | ||
68 | TP_fast_assign( | |
69 | __entry->timer = timer; | |
70 | __entry->function = timer->function; | |
71 | __entry->expires = expires; | |
72 | __entry->now = jiffies; | |
0eeda71b | 73 | __entry->flags = flags; |
2b022e3d XG |
74 | ), |
75 | ||
8a58a34b | 76 | TP_printk("timer=%p function=%pf expires=%lu [timeout=%ld] cpu=%u idx=%u flags=%s", |
2b022e3d | 77 | __entry->timer, __entry->function, __entry->expires, |
8a58a34b TG |
78 | (long)__entry->expires - __entry->now, |
79 | __entry->flags & TIMER_CPUMASK, | |
80 | __entry->flags >> TIMER_ARRAYSHIFT, | |
81 | decode_timer_flags(__entry->flags & TIMER_TRACE_FLAGMASK)) | |
2b022e3d XG |
82 | ); |
83 | ||
84 | /** | |
85 | * timer_expire_entry - called immediately before the timer callback | |
86 | * @timer: pointer to struct timer_list | |
87 | * | |
88 | * Allows to determine the timer latency. | |
89 | */ | |
90 | TRACE_EVENT(timer_expire_entry, | |
91 | ||
92 | TP_PROTO(struct timer_list *timer), | |
93 | ||
94 | TP_ARGS(timer), | |
95 | ||
96 | TP_STRUCT__entry( | |
97 | __field( void *, timer ) | |
98 | __field( unsigned long, now ) | |
ede1b429 | 99 | __field( void *, function) |
2b022e3d XG |
100 | ), |
101 | ||
102 | TP_fast_assign( | |
103 | __entry->timer = timer; | |
104 | __entry->now = jiffies; | |
ede1b429 | 105 | __entry->function = timer->function; |
2b022e3d XG |
106 | ), |
107 | ||
ede1b429 | 108 | TP_printk("timer=%p function=%pf now=%lu", __entry->timer, __entry->function,__entry->now) |
2b022e3d XG |
109 | ); |
110 | ||
111 | /** | |
112 | * timer_expire_exit - called immediately after the timer callback returns | |
113 | * @timer: pointer to struct timer_list | |
114 | * | |
115 | * When used in combination with the timer_expire_entry tracepoint we can | |
116 | * determine the runtime of the timer callback function. | |
117 | * | |
118 | * NOTE: Do NOT derefernce timer in TP_fast_assign. The pointer might | |
119 | * be invalid. We solely track the pointer. | |
120 | */ | |
363d0f64 | 121 | DEFINE_EVENT(timer_class, timer_expire_exit, |
2b022e3d XG |
122 | |
123 | TP_PROTO(struct timer_list *timer), | |
124 | ||
363d0f64 | 125 | TP_ARGS(timer) |
2b022e3d XG |
126 | ); |
127 | ||
128 | /** | |
129 | * timer_cancel - called when the timer is canceled | |
130 | * @timer: pointer to struct timer_list | |
131 | */ | |
363d0f64 | 132 | DEFINE_EVENT(timer_class, timer_cancel, |
2b022e3d XG |
133 | |
134 | TP_PROTO(struct timer_list *timer), | |
135 | ||
363d0f64 | 136 | TP_ARGS(timer) |
2b022e3d XG |
137 | ); |
138 | ||
9d6e5bac AMG |
139 | #define decode_clockid(type) \ |
140 | __print_symbolic(type, \ | |
141 | { CLOCK_REALTIME, "CLOCK_REALTIME" }, \ | |
142 | { CLOCK_MONOTONIC, "CLOCK_MONOTONIC" }, \ | |
143 | { CLOCK_BOOTTIME, "CLOCK_BOOTTIME" }, \ | |
144 | { CLOCK_TAI, "CLOCK_TAI" }) | |
145 | ||
146 | #define decode_hrtimer_mode(mode) \ | |
147 | __print_symbolic(mode, \ | |
148 | { HRTIMER_MODE_ABS, "ABS" }, \ | |
149 | { HRTIMER_MODE_REL, "REL" }, \ | |
150 | { HRTIMER_MODE_ABS_PINNED, "ABS|PINNED" }, \ | |
151 | { HRTIMER_MODE_REL_PINNED, "REL|PINNED" }) | |
152 | ||
c6a2a177 XG |
153 | /** |
154 | * hrtimer_init - called when the hrtimer is initialized | |
cf2fbdd2 | 155 | * @hrtimer: pointer to struct hrtimer |
c6a2a177 XG |
156 | * @clockid: the hrtimers clock |
157 | * @mode: the hrtimers mode | |
158 | */ | |
159 | TRACE_EVENT(hrtimer_init, | |
160 | ||
434a83c3 | 161 | TP_PROTO(struct hrtimer *hrtimer, clockid_t clockid, |
c6a2a177 XG |
162 | enum hrtimer_mode mode), |
163 | ||
434a83c3 | 164 | TP_ARGS(hrtimer, clockid, mode), |
c6a2a177 XG |
165 | |
166 | TP_STRUCT__entry( | |
434a83c3 | 167 | __field( void *, hrtimer ) |
c6a2a177 XG |
168 | __field( clockid_t, clockid ) |
169 | __field( enum hrtimer_mode, mode ) | |
170 | ), | |
171 | ||
172 | TP_fast_assign( | |
434a83c3 | 173 | __entry->hrtimer = hrtimer; |
c6a2a177 XG |
174 | __entry->clockid = clockid; |
175 | __entry->mode = mode; | |
176 | ), | |
177 | ||
434a83c3 | 178 | TP_printk("hrtimer=%p clockid=%s mode=%s", __entry->hrtimer, |
9d6e5bac AMG |
179 | decode_clockid(__entry->clockid), |
180 | decode_hrtimer_mode(__entry->mode)) | |
c6a2a177 XG |
181 | ); |
182 | ||
183 | /** | |
184 | * hrtimer_start - called when the hrtimer is started | |
cf2fbdd2 | 185 | * @hrtimer: pointer to struct hrtimer |
c6a2a177 XG |
186 | */ |
187 | TRACE_EVENT(hrtimer_start, | |
188 | ||
434a83c3 | 189 | TP_PROTO(struct hrtimer *hrtimer), |
c6a2a177 | 190 | |
434a83c3 | 191 | TP_ARGS(hrtimer), |
c6a2a177 XG |
192 | |
193 | TP_STRUCT__entry( | |
434a83c3 | 194 | __field( void *, hrtimer ) |
c6a2a177 XG |
195 | __field( void *, function ) |
196 | __field( s64, expires ) | |
197 | __field( s64, softexpires ) | |
198 | ), | |
199 | ||
200 | TP_fast_assign( | |
434a83c3 IM |
201 | __entry->hrtimer = hrtimer; |
202 | __entry->function = hrtimer->function; | |
2456e855 TG |
203 | __entry->expires = hrtimer_get_expires(hrtimer); |
204 | __entry->softexpires = hrtimer_get_softexpires(hrtimer); | |
c6a2a177 XG |
205 | ), |
206 | ||
434a83c3 IM |
207 | TP_printk("hrtimer=%p function=%pf expires=%llu softexpires=%llu", |
208 | __entry->hrtimer, __entry->function, | |
2456e855 TG |
209 | (unsigned long long) __entry->expires, |
210 | (unsigned long long) __entry->softexpires) | |
c6a2a177 XG |
211 | ); |
212 | ||
213 | /** | |
cf2fbdd2 MI |
214 | * hrtimer_expire_entry - called immediately before the hrtimer callback |
215 | * @hrtimer: pointer to struct hrtimer | |
c6a2a177 XG |
216 | * @now: pointer to variable which contains current time of the |
217 | * timers base. | |
218 | * | |
219 | * Allows to determine the timer latency. | |
220 | */ | |
221 | TRACE_EVENT(hrtimer_expire_entry, | |
222 | ||
434a83c3 | 223 | TP_PROTO(struct hrtimer *hrtimer, ktime_t *now), |
c6a2a177 | 224 | |
434a83c3 | 225 | TP_ARGS(hrtimer, now), |
c6a2a177 XG |
226 | |
227 | TP_STRUCT__entry( | |
434a83c3 | 228 | __field( void *, hrtimer ) |
c6a2a177 | 229 | __field( s64, now ) |
ede1b429 | 230 | __field( void *, function) |
c6a2a177 XG |
231 | ), |
232 | ||
233 | TP_fast_assign( | |
434a83c3 | 234 | __entry->hrtimer = hrtimer; |
2456e855 | 235 | __entry->now = *now; |
ede1b429 | 236 | __entry->function = hrtimer->function; |
c6a2a177 XG |
237 | ), |
238 | ||
ede1b429 | 239 | TP_printk("hrtimer=%p function=%pf now=%llu", __entry->hrtimer, __entry->function, |
2456e855 TG |
240 | (unsigned long long) __entry->now) |
241 | ); | |
c6a2a177 | 242 | |
363d0f64 | 243 | DECLARE_EVENT_CLASS(hrtimer_class, |
c6a2a177 | 244 | |
434a83c3 | 245 | TP_PROTO(struct hrtimer *hrtimer), |
c6a2a177 | 246 | |
434a83c3 | 247 | TP_ARGS(hrtimer), |
c6a2a177 XG |
248 | |
249 | TP_STRUCT__entry( | |
434a83c3 | 250 | __field( void *, hrtimer ) |
c6a2a177 XG |
251 | ), |
252 | ||
253 | TP_fast_assign( | |
434a83c3 | 254 | __entry->hrtimer = hrtimer; |
c6a2a177 XG |
255 | ), |
256 | ||
434a83c3 | 257 | TP_printk("hrtimer=%p", __entry->hrtimer) |
c6a2a177 XG |
258 | ); |
259 | ||
260 | /** | |
363d0f64 | 261 | * hrtimer_expire_exit - called immediately after the hrtimer callback returns |
cf2fbdd2 | 262 | * @hrtimer: pointer to struct hrtimer |
363d0f64 LZ |
263 | * |
264 | * When used in combination with the hrtimer_expire_entry tracepoint we can | |
265 | * determine the runtime of the callback function. | |
c6a2a177 | 266 | */ |
363d0f64 | 267 | DEFINE_EVENT(hrtimer_class, hrtimer_expire_exit, |
c6a2a177 | 268 | |
434a83c3 | 269 | TP_PROTO(struct hrtimer *hrtimer), |
c6a2a177 | 270 | |
363d0f64 LZ |
271 | TP_ARGS(hrtimer) |
272 | ); | |
c6a2a177 | 273 | |
363d0f64 LZ |
274 | /** |
275 | * hrtimer_cancel - called when the hrtimer is canceled | |
276 | * @hrtimer: pointer to struct hrtimer | |
277 | */ | |
278 | DEFINE_EVENT(hrtimer_class, hrtimer_cancel, | |
c6a2a177 | 279 | |
363d0f64 | 280 | TP_PROTO(struct hrtimer *hrtimer), |
c6a2a177 | 281 | |
363d0f64 | 282 | TP_ARGS(hrtimer) |
c6a2a177 XG |
283 | ); |
284 | ||
3f0a525e XG |
285 | /** |
286 | * itimer_state - called when itimer is started or canceled | |
287 | * @which: name of the interval timer | |
288 | * @value: the itimers value, itimer is canceled if value->it_value is | |
289 | * zero, otherwise it is started | |
290 | * @expires: the itimers expiry time | |
291 | */ | |
292 | TRACE_EVENT(itimer_state, | |
293 | ||
294 | TP_PROTO(int which, const struct itimerval *const value, | |
858cf3a8 | 295 | unsigned long long expires), |
3f0a525e XG |
296 | |
297 | TP_ARGS(which, value, expires), | |
298 | ||
299 | TP_STRUCT__entry( | |
858cf3a8 FW |
300 | __field( int, which ) |
301 | __field( unsigned long long, expires ) | |
302 | __field( long, value_sec ) | |
303 | __field( long, value_usec ) | |
304 | __field( long, interval_sec ) | |
305 | __field( long, interval_usec ) | |
3f0a525e XG |
306 | ), |
307 | ||
308 | TP_fast_assign( | |
309 | __entry->which = which; | |
310 | __entry->expires = expires; | |
311 | __entry->value_sec = value->it_value.tv_sec; | |
312 | __entry->value_usec = value->it_value.tv_usec; | |
313 | __entry->interval_sec = value->it_interval.tv_sec; | |
314 | __entry->interval_usec = value->it_interval.tv_usec; | |
315 | ), | |
316 | ||
e9c0748b | 317 | TP_printk("which=%d expires=%llu it_value=%ld.%ld it_interval=%ld.%ld", |
858cf3a8 | 318 | __entry->which, __entry->expires, |
3f0a525e XG |
319 | __entry->value_sec, __entry->value_usec, |
320 | __entry->interval_sec, __entry->interval_usec) | |
321 | ); | |
322 | ||
323 | /** | |
324 | * itimer_expire - called when itimer expires | |
325 | * @which: type of the interval timer | |
326 | * @pid: pid of the process which owns the timer | |
327 | * @now: current time, used to calculate the latency of itimer | |
328 | */ | |
329 | TRACE_EVENT(itimer_expire, | |
330 | ||
858cf3a8 | 331 | TP_PROTO(int which, struct pid *pid, unsigned long long now), |
3f0a525e XG |
332 | |
333 | TP_ARGS(which, pid, now), | |
334 | ||
335 | TP_STRUCT__entry( | |
858cf3a8 FW |
336 | __field( int , which ) |
337 | __field( pid_t, pid ) | |
338 | __field( unsigned long long, now ) | |
3f0a525e XG |
339 | ), |
340 | ||
341 | TP_fast_assign( | |
342 | __entry->which = which; | |
343 | __entry->now = now; | |
344 | __entry->pid = pid_nr(pid); | |
345 | ), | |
346 | ||
e9c0748b | 347 | TP_printk("which=%d pid=%d now=%llu", __entry->which, |
858cf3a8 | 348 | (int) __entry->pid, __entry->now) |
3f0a525e XG |
349 | ); |
350 | ||
2c82d1be | 351 | #ifdef CONFIG_NO_HZ_COMMON |
e6e6cc22 FW |
352 | |
353 | #define TICK_DEP_NAMES \ | |
c87edb36 | 354 | tick_dep_mask_name(NONE) \ |
e6e6cc22 FW |
355 | tick_dep_name(POSIX_TIMER) \ |
356 | tick_dep_name(PERF_EVENTS) \ | |
357 | tick_dep_name(SCHED) \ | |
358 | tick_dep_name_end(CLOCK_UNSTABLE) | |
359 | ||
360 | #undef tick_dep_name | |
c87edb36 | 361 | #undef tick_dep_mask_name |
e6e6cc22 FW |
362 | #undef tick_dep_name_end |
363 | ||
c87edb36 SRRH |
364 | /* The MASK will convert to their bits and they need to be processed too */ |
365 | #define tick_dep_name(sdep) TRACE_DEFINE_ENUM(TICK_DEP_BIT_##sdep); \ | |
366 | TRACE_DEFINE_ENUM(TICK_DEP_MASK_##sdep); | |
367 | #define tick_dep_name_end(sdep) TRACE_DEFINE_ENUM(TICK_DEP_BIT_##sdep); \ | |
368 | TRACE_DEFINE_ENUM(TICK_DEP_MASK_##sdep); | |
369 | /* NONE only has a mask defined for it */ | |
370 | #define tick_dep_mask_name(sdep) TRACE_DEFINE_ENUM(TICK_DEP_MASK_##sdep); | |
e6e6cc22 FW |
371 | |
372 | TICK_DEP_NAMES | |
373 | ||
374 | #undef tick_dep_name | |
c87edb36 | 375 | #undef tick_dep_mask_name |
e6e6cc22 FW |
376 | #undef tick_dep_name_end |
377 | ||
378 | #define tick_dep_name(sdep) { TICK_DEP_MASK_##sdep, #sdep }, | |
c87edb36 | 379 | #define tick_dep_mask_name(sdep) { TICK_DEP_MASK_##sdep, #sdep }, |
e6e6cc22 FW |
380 | #define tick_dep_name_end(sdep) { TICK_DEP_MASK_##sdep, #sdep } |
381 | ||
382 | #define show_tick_dep_name(val) \ | |
383 | __print_symbolic(val, TICK_DEP_NAMES) | |
384 | ||
cb41a290 FW |
385 | TRACE_EVENT(tick_stop, |
386 | ||
e6e6cc22 | 387 | TP_PROTO(int success, int dependency), |
cb41a290 | 388 | |
e6e6cc22 | 389 | TP_ARGS(success, dependency), |
cb41a290 FW |
390 | |
391 | TP_STRUCT__entry( | |
392 | __field( int , success ) | |
e6e6cc22 | 393 | __field( int , dependency ) |
cb41a290 FW |
394 | ), |
395 | ||
396 | TP_fast_assign( | |
397 | __entry->success = success; | |
e6e6cc22 | 398 | __entry->dependency = dependency; |
cb41a290 FW |
399 | ), |
400 | ||
e6e6cc22 FW |
401 | TP_printk("success=%d dependency=%s", __entry->success, \ |
402 | show_tick_dep_name(__entry->dependency)) | |
cb41a290 FW |
403 | ); |
404 | #endif | |
405 | ||
2b022e3d XG |
406 | #endif /* _TRACE_TIMER_H */ |
407 | ||
408 | /* This part must be outside protection */ | |
409 | #include <trace/define_trace.h> |