1 /* SPDX-License-Identifier: GPL-2.0 */
3 #define TRACE_SYSTEM timer
5 #if !defined(_TRACE_TIMER_H) || defined(TRACE_HEADER_MULTI_READ)
8 #include <linux/tracepoint.h>
9 #include <linux/hrtimer.h>
10 #include <linux/timer.h>
12 DECLARE_EVENT_CLASS(timer_class
,
14 TP_PROTO(struct timer_list
*timer
),
19 __field( void *, timer
)
23 __entry
->timer
= timer
;
26 TP_printk("timer=%p", __entry
->timer
)
30 * timer_init - called when the timer is initialized
31 * @timer: pointer to struct timer_list
33 DEFINE_EVENT(timer_class
, timer_init
,
35 TP_PROTO(struct timer_list
*timer
),
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" })
48 * timer_start - called when the timer is started
49 * @timer: pointer to struct timer_list
50 * @bucket_expiry: the bucket expiry time
52 TRACE_EVENT(timer_start
,
54 TP_PROTO(struct timer_list
*timer
,
55 unsigned long bucket_expiry
),
57 TP_ARGS(timer
, bucket_expiry
),
60 __field( void *, timer
)
61 __field( void *, function
)
62 __field( unsigned long, expires
)
63 __field( unsigned long, bucket_expiry
)
64 __field( unsigned long, now
)
65 __field( unsigned int, flags
)
69 __entry
->timer
= timer
;
70 __entry
->function
= timer
->function
;
71 __entry
->expires
= timer
->expires
;
72 __entry
->bucket_expiry
= bucket_expiry
;
73 __entry
->now
= jiffies
;
74 __entry
->flags
= timer
->flags
;
77 TP_printk("timer=%p function=%ps expires=%lu [timeout=%ld] bucket_expiry=%lu cpu=%u idx=%u flags=%s",
78 __entry
->timer
, __entry
->function
, __entry
->expires
,
79 (long)__entry
->expires
- __entry
->now
,
80 __entry
->bucket_expiry
, __entry
->flags
& TIMER_CPUMASK
,
81 __entry
->flags
>> TIMER_ARRAYSHIFT
,
82 decode_timer_flags(__entry
->flags
& TIMER_TRACE_FLAGMASK
))
86 * timer_expire_entry - called immediately before the timer callback
87 * @timer: pointer to struct timer_list
88 * @baseclk: value of timer_base::clk when timer expires
90 * Allows to determine the timer latency.
92 TRACE_EVENT(timer_expire_entry
,
94 TP_PROTO(struct timer_list
*timer
, unsigned long baseclk
),
96 TP_ARGS(timer
, baseclk
),
99 __field( void *, timer
)
100 __field( unsigned long, now
)
101 __field( void *, function
)
102 __field( unsigned long, baseclk
)
106 __entry
->timer
= timer
;
107 __entry
->now
= jiffies
;
108 __entry
->function
= timer
->function
;
109 __entry
->baseclk
= baseclk
;
112 TP_printk("timer=%p function=%ps now=%lu baseclk=%lu",
113 __entry
->timer
, __entry
->function
, __entry
->now
,
118 * timer_expire_exit - called immediately after the timer callback returns
119 * @timer: pointer to struct timer_list
121 * When used in combination with the timer_expire_entry tracepoint we can
122 * determine the runtime of the timer callback function.
124 * NOTE: Do NOT dereference timer in TP_fast_assign. The pointer might
125 * be invalid. We solely track the pointer.
127 DEFINE_EVENT(timer_class
, timer_expire_exit
,
129 TP_PROTO(struct timer_list
*timer
),
135 * timer_cancel - called when the timer is canceled
136 * @timer: pointer to struct timer_list
138 DEFINE_EVENT(timer_class
, timer_cancel
,
140 TP_PROTO(struct timer_list
*timer
),
145 TRACE_EVENT(timer_base_idle
,
147 TP_PROTO(bool is_idle
, unsigned int cpu
),
149 TP_ARGS(is_idle
, cpu
),
152 __field( bool, is_idle
)
153 __field( unsigned int, cpu
)
157 __entry
->is_idle
= is_idle
;
161 TP_printk("is_idle=%d cpu=%d",
162 __entry
->is_idle
, __entry
->cpu
)
165 #define decode_clockid(type) \
166 __print_symbolic(type, \
167 { CLOCK_REALTIME, "CLOCK_REALTIME" }, \
168 { CLOCK_MONOTONIC, "CLOCK_MONOTONIC" }, \
169 { CLOCK_BOOTTIME, "CLOCK_BOOTTIME" }, \
170 { CLOCK_TAI, "CLOCK_TAI" })
172 #define decode_hrtimer_mode(mode) \
173 __print_symbolic(mode, \
174 { HRTIMER_MODE_ABS, "ABS" }, \
175 { HRTIMER_MODE_REL, "REL" }, \
176 { HRTIMER_MODE_ABS_PINNED, "ABS|PINNED" }, \
177 { HRTIMER_MODE_REL_PINNED, "REL|PINNED" }, \
178 { HRTIMER_MODE_ABS_SOFT, "ABS|SOFT" }, \
179 { HRTIMER_MODE_REL_SOFT, "REL|SOFT" }, \
180 { HRTIMER_MODE_ABS_PINNED_SOFT, "ABS|PINNED|SOFT" }, \
181 { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" }, \
182 { HRTIMER_MODE_ABS_HARD, "ABS|HARD" }, \
183 { HRTIMER_MODE_REL_HARD, "REL|HARD" }, \
184 { HRTIMER_MODE_ABS_PINNED_HARD, "ABS|PINNED|HARD" }, \
185 { HRTIMER_MODE_REL_PINNED_HARD, "REL|PINNED|HARD" })
188 * hrtimer_init - called when the hrtimer is initialized
189 * @hrtimer: pointer to struct hrtimer
190 * @clockid: the hrtimers clock
191 * @mode: the hrtimers mode
193 TRACE_EVENT(hrtimer_init
,
195 TP_PROTO(struct hrtimer
*hrtimer
, clockid_t clockid
,
196 enum hrtimer_mode mode
),
198 TP_ARGS(hrtimer
, clockid
, mode
),
201 __field( void *, hrtimer
)
202 __field( clockid_t
, clockid
)
203 __field( enum hrtimer_mode
, mode
)
207 __entry
->hrtimer
= hrtimer
;
208 __entry
->clockid
= clockid
;
209 __entry
->mode
= mode
;
212 TP_printk("hrtimer=%p clockid=%s mode=%s", __entry
->hrtimer
,
213 decode_clockid(__entry
->clockid
),
214 decode_hrtimer_mode(__entry
->mode
))
218 * hrtimer_start - called when the hrtimer is started
219 * @hrtimer: pointer to struct hrtimer
220 * @mode: the hrtimers mode
222 TRACE_EVENT(hrtimer_start
,
224 TP_PROTO(struct hrtimer
*hrtimer
, enum hrtimer_mode mode
),
226 TP_ARGS(hrtimer
, mode
),
229 __field( void *, hrtimer
)
230 __field( void *, function
)
231 __field( s64
, expires
)
232 __field( s64
, softexpires
)
233 __field( enum hrtimer_mode
, mode
)
237 __entry
->hrtimer
= hrtimer
;
238 __entry
->function
= hrtimer
->function
;
239 __entry
->expires
= hrtimer_get_expires(hrtimer
);
240 __entry
->softexpires
= hrtimer_get_softexpires(hrtimer
);
241 __entry
->mode
= mode
;
244 TP_printk("hrtimer=%p function=%ps expires=%llu softexpires=%llu "
245 "mode=%s", __entry
->hrtimer
, __entry
->function
,
246 (unsigned long long) __entry
->expires
,
247 (unsigned long long) __entry
->softexpires
,
248 decode_hrtimer_mode(__entry
->mode
))
252 * hrtimer_expire_entry - called immediately before the hrtimer callback
253 * @hrtimer: pointer to struct hrtimer
254 * @now: pointer to variable which contains current time of the
257 * Allows to determine the timer latency.
259 TRACE_EVENT(hrtimer_expire_entry
,
261 TP_PROTO(struct hrtimer
*hrtimer
, ktime_t
*now
),
263 TP_ARGS(hrtimer
, now
),
266 __field( void *, hrtimer
)
268 __field( void *, function
)
272 __entry
->hrtimer
= hrtimer
;
274 __entry
->function
= hrtimer
->function
;
277 TP_printk("hrtimer=%p function=%ps now=%llu",
278 __entry
->hrtimer
, __entry
->function
,
279 (unsigned long long) __entry
->now
)
282 DECLARE_EVENT_CLASS(hrtimer_class
,
284 TP_PROTO(struct hrtimer
*hrtimer
),
289 __field( void *, hrtimer
)
293 __entry
->hrtimer
= hrtimer
;
296 TP_printk("hrtimer=%p", __entry
->hrtimer
)
300 * hrtimer_expire_exit - called immediately after the hrtimer callback returns
301 * @hrtimer: pointer to struct hrtimer
303 * When used in combination with the hrtimer_expire_entry tracepoint we can
304 * determine the runtime of the callback function.
306 DEFINE_EVENT(hrtimer_class
, hrtimer_expire_exit
,
308 TP_PROTO(struct hrtimer
*hrtimer
),
314 * hrtimer_cancel - called when the hrtimer is canceled
315 * @hrtimer: pointer to struct hrtimer
317 DEFINE_EVENT(hrtimer_class
, hrtimer_cancel
,
319 TP_PROTO(struct hrtimer
*hrtimer
),
325 * itimer_state - called when itimer is started or canceled
326 * @which: name of the interval timer
327 * @value: the itimers value, itimer is canceled if value->it_value is
328 * zero, otherwise it is started
329 * @expires: the itimers expiry time
331 TRACE_EVENT(itimer_state
,
333 TP_PROTO(int which
, const struct itimerspec64
*const value
,
334 unsigned long long expires
),
336 TP_ARGS(which
, value
, expires
),
339 __field( int, which
)
340 __field( unsigned long long, expires
)
341 __field( long, value_sec
)
342 __field( long, value_nsec
)
343 __field( long, interval_sec
)
344 __field( long, interval_nsec
)
348 __entry
->which
= which
;
349 __entry
->expires
= expires
;
350 __entry
->value_sec
= value
->it_value
.tv_sec
;
351 __entry
->value_nsec
= value
->it_value
.tv_nsec
;
352 __entry
->interval_sec
= value
->it_interval
.tv_sec
;
353 __entry
->interval_nsec
= value
->it_interval
.tv_nsec
;
356 TP_printk("which=%d expires=%llu it_value=%ld.%06ld it_interval=%ld.%06ld",
357 __entry
->which
, __entry
->expires
,
358 __entry
->value_sec
, __entry
->value_nsec
/ NSEC_PER_USEC
,
359 __entry
->interval_sec
, __entry
->interval_nsec
/ NSEC_PER_USEC
)
363 * itimer_expire - called when itimer expires
364 * @which: type of the interval timer
365 * @pid: pid of the process which owns the timer
366 * @now: current time, used to calculate the latency of itimer
368 TRACE_EVENT(itimer_expire
,
370 TP_PROTO(int which
, struct pid
*pid
, unsigned long long now
),
372 TP_ARGS(which
, pid
, now
),
375 __field( int , which
)
376 __field( pid_t
, pid
)
377 __field( unsigned long long, now
)
381 __entry
->which
= which
;
383 __entry
->pid
= pid_nr(pid
);
386 TP_printk("which=%d pid=%d now=%llu", __entry
->which
,
387 (int) __entry
->pid
, __entry
->now
)
390 #ifdef CONFIG_NO_HZ_COMMON
392 #define TICK_DEP_NAMES \
393 tick_dep_mask_name(NONE) \
394 tick_dep_name(POSIX_TIMER) \
395 tick_dep_name(PERF_EVENTS) \
396 tick_dep_name(SCHED) \
397 tick_dep_name(CLOCK_UNSTABLE) \
399 tick_dep_name_end(RCU_EXP)
402 #undef tick_dep_mask_name
403 #undef tick_dep_name_end
405 /* The MASK will convert to their bits and they need to be processed too */
406 #define tick_dep_name(sdep) TRACE_DEFINE_ENUM(TICK_DEP_BIT_##sdep); \
407 TRACE_DEFINE_ENUM(TICK_DEP_MASK_##sdep);
408 #define tick_dep_name_end(sdep) TRACE_DEFINE_ENUM(TICK_DEP_BIT_##sdep); \
409 TRACE_DEFINE_ENUM(TICK_DEP_MASK_##sdep);
410 /* NONE only has a mask defined for it */
411 #define tick_dep_mask_name(sdep) TRACE_DEFINE_ENUM(TICK_DEP_MASK_##sdep);
416 #undef tick_dep_mask_name
417 #undef tick_dep_name_end
419 #define tick_dep_name(sdep) { TICK_DEP_MASK_##sdep, #sdep },
420 #define tick_dep_mask_name(sdep) { TICK_DEP_MASK_##sdep, #sdep },
421 #define tick_dep_name_end(sdep) { TICK_DEP_MASK_##sdep, #sdep }
423 #define show_tick_dep_name(val) \
424 __print_symbolic(val, TICK_DEP_NAMES)
426 TRACE_EVENT(tick_stop
,
428 TP_PROTO(int success
, int dependency
),
430 TP_ARGS(success
, dependency
),
433 __field( int , success
)
434 __field( int , dependency
)
438 __entry
->success
= success
;
439 __entry
->dependency
= dependency
;
442 TP_printk("success=%d dependency=%s", __entry
->success
, \
443 show_tick_dep_name(__entry
->dependency
))
447 #endif /* _TRACE_TIMER_H */
449 /* This part must be outside protection */
450 #include <trace/define_trace.h>