1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #undef TRACE_SYSTEM |
3 | #define TRACE_SYSTEM power |
4 | |
5 | #if !defined(_TRACE_POWER_H) || defined(TRACE_HEADER_MULTI_READ) |
6 | #define _TRACE_POWER_H |
7 | |
8 | #include <linux/cpufreq.h> |
9 | #include <linux/ktime.h> |
10 | #include <linux/pm_qos.h> |
11 | #include <linux/tracepoint.h> |
12 | #include <linux/trace_events.h> |
13 | |
14 | #define TPS(x) tracepoint_string(x) |
15 | |
16 | DECLARE_EVENT_CLASS(cpu, |
17 | |
18 | TP_PROTO(unsigned int state, unsigned int cpu_id), |
19 | |
20 | TP_ARGS(state, cpu_id), |
21 | |
22 | TP_STRUCT__entry( |
23 | __field( u32, state ) |
24 | __field( u32, cpu_id ) |
25 | ), |
26 | |
27 | TP_fast_assign( |
28 | __entry->state = state; |
29 | __entry->cpu_id = cpu_id; |
30 | ), |
31 | |
32 | TP_printk("state=%lu cpu_id=%lu" , (unsigned long)__entry->state, |
33 | (unsigned long)__entry->cpu_id) |
34 | ); |
35 | |
36 | DEFINE_EVENT(cpu, cpu_idle, |
37 | |
38 | TP_PROTO(unsigned int state, unsigned int cpu_id), |
39 | |
40 | TP_ARGS(state, cpu_id) |
41 | ); |
42 | |
43 | TRACE_EVENT(cpu_idle_miss, |
44 | |
45 | TP_PROTO(unsigned int cpu_id, unsigned int state, bool below), |
46 | |
47 | TP_ARGS(cpu_id, state, below), |
48 | |
49 | TP_STRUCT__entry( |
50 | __field(u32, cpu_id) |
51 | __field(u32, state) |
52 | __field(bool, below) |
53 | ), |
54 | |
55 | TP_fast_assign( |
56 | __entry->cpu_id = cpu_id; |
57 | __entry->state = state; |
58 | __entry->below = below; |
59 | ), |
60 | |
61 | TP_printk("cpu_id=%lu state=%lu type=%s" , (unsigned long)__entry->cpu_id, |
62 | (unsigned long)__entry->state, (__entry->below)?"below" :"above" ) |
63 | ); |
64 | |
65 | TRACE_EVENT(powernv_throttle, |
66 | |
67 | TP_PROTO(int chip_id, const char *reason, int pmax), |
68 | |
69 | TP_ARGS(chip_id, reason, pmax), |
70 | |
71 | TP_STRUCT__entry( |
72 | __field(int, chip_id) |
73 | __string(reason, reason) |
74 | __field(int, pmax) |
75 | ), |
76 | |
77 | TP_fast_assign( |
78 | __entry->chip_id = chip_id; |
79 | __assign_str(reason, reason); |
80 | __entry->pmax = pmax; |
81 | ), |
82 | |
83 | TP_printk("Chip %d Pmax %d %s" , __entry->chip_id, |
84 | __entry->pmax, __get_str(reason)) |
85 | ); |
86 | |
87 | TRACE_EVENT(pstate_sample, |
88 | |
89 | TP_PROTO(u32 core_busy, |
90 | u32 scaled_busy, |
91 | u32 from, |
92 | u32 to, |
93 | u64 mperf, |
94 | u64 aperf, |
95 | u64 tsc, |
96 | u32 freq, |
97 | u32 io_boost |
98 | ), |
99 | |
100 | TP_ARGS(core_busy, |
101 | scaled_busy, |
102 | from, |
103 | to, |
104 | mperf, |
105 | aperf, |
106 | tsc, |
107 | freq, |
108 | io_boost |
109 | ), |
110 | |
111 | TP_STRUCT__entry( |
112 | __field(u32, core_busy) |
113 | __field(u32, scaled_busy) |
114 | __field(u32, from) |
115 | __field(u32, to) |
116 | __field(u64, mperf) |
117 | __field(u64, aperf) |
118 | __field(u64, tsc) |
119 | __field(u32, freq) |
120 | __field(u32, io_boost) |
121 | ), |
122 | |
123 | TP_fast_assign( |
124 | __entry->core_busy = core_busy; |
125 | __entry->scaled_busy = scaled_busy; |
126 | __entry->from = from; |
127 | __entry->to = to; |
128 | __entry->mperf = mperf; |
129 | __entry->aperf = aperf; |
130 | __entry->tsc = tsc; |
131 | __entry->freq = freq; |
132 | __entry->io_boost = io_boost; |
133 | ), |
134 | |
135 | TP_printk("core_busy=%lu scaled=%lu from=%lu to=%lu mperf=%llu aperf=%llu tsc=%llu freq=%lu io_boost=%lu" , |
136 | (unsigned long)__entry->core_busy, |
137 | (unsigned long)__entry->scaled_busy, |
138 | (unsigned long)__entry->from, |
139 | (unsigned long)__entry->to, |
140 | (unsigned long long)__entry->mperf, |
141 | (unsigned long long)__entry->aperf, |
142 | (unsigned long long)__entry->tsc, |
143 | (unsigned long)__entry->freq, |
144 | (unsigned long)__entry->io_boost |
145 | ) |
146 | |
147 | ); |
148 | |
149 | /* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ |
150 | #ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING |
151 | #define _PWR_EVENT_AVOID_DOUBLE_DEFINING |
152 | |
153 | #define PWR_EVENT_EXIT -1 |
154 | #endif |
155 | |
156 | #define pm_verb_symbolic(event) \ |
157 | __print_symbolic(event, \ |
158 | { PM_EVENT_SUSPEND, "suspend" }, \ |
159 | { PM_EVENT_RESUME, "resume" }, \ |
160 | { PM_EVENT_FREEZE, "freeze" }, \ |
161 | { PM_EVENT_QUIESCE, "quiesce" }, \ |
162 | { PM_EVENT_HIBERNATE, "hibernate" }, \ |
163 | { PM_EVENT_THAW, "thaw" }, \ |
164 | { PM_EVENT_RESTORE, "restore" }, \ |
165 | { PM_EVENT_RECOVER, "recover" }) |
166 | |
167 | DEFINE_EVENT(cpu, cpu_frequency, |
168 | |
169 | TP_PROTO(unsigned int frequency, unsigned int cpu_id), |
170 | |
171 | TP_ARGS(frequency, cpu_id) |
172 | ); |
173 | |
174 | TRACE_EVENT(cpu_frequency_limits, |
175 | |
176 | TP_PROTO(struct cpufreq_policy *policy), |
177 | |
178 | TP_ARGS(policy), |
179 | |
180 | TP_STRUCT__entry( |
181 | __field(u32, min_freq) |
182 | __field(u32, max_freq) |
183 | __field(u32, cpu_id) |
184 | ), |
185 | |
186 | TP_fast_assign( |
187 | __entry->min_freq = policy->min; |
188 | __entry->max_freq = policy->max; |
189 | __entry->cpu_id = policy->cpu; |
190 | ), |
191 | |
192 | TP_printk("min=%lu max=%lu cpu_id=%lu" , |
193 | (unsigned long)__entry->min_freq, |
194 | (unsigned long)__entry->max_freq, |
195 | (unsigned long)__entry->cpu_id) |
196 | ); |
197 | |
198 | TRACE_EVENT(device_pm_callback_start, |
199 | |
200 | TP_PROTO(struct device *dev, const char *pm_ops, int event), |
201 | |
202 | TP_ARGS(dev, pm_ops, event), |
203 | |
204 | TP_STRUCT__entry( |
205 | __string(device, dev_name(dev)) |
206 | __string(driver, dev_driver_string(dev)) |
207 | __string(parent, dev->parent ? dev_name(dev->parent) : "none" ) |
208 | __string(pm_ops, pm_ops ? pm_ops : "none " ) |
209 | __field(int, event) |
210 | ), |
211 | |
212 | TP_fast_assign( |
213 | __assign_str(device, dev_name(dev)); |
214 | __assign_str(driver, dev_driver_string(dev)); |
215 | __assign_str(parent, |
216 | dev->parent ? dev_name(dev->parent) : "none" ); |
217 | __assign_str(pm_ops, pm_ops ? pm_ops : "none " ); |
218 | __entry->event = event; |
219 | ), |
220 | |
221 | TP_printk("%s %s, parent: %s, %s[%s]" , __get_str(driver), |
222 | __get_str(device), __get_str(parent), __get_str(pm_ops), |
223 | pm_verb_symbolic(__entry->event)) |
224 | ); |
225 | |
226 | TRACE_EVENT(device_pm_callback_end, |
227 | |
228 | TP_PROTO(struct device *dev, int error), |
229 | |
230 | TP_ARGS(dev, error), |
231 | |
232 | TP_STRUCT__entry( |
233 | __string(device, dev_name(dev)) |
234 | __string(driver, dev_driver_string(dev)) |
235 | __field(int, error) |
236 | ), |
237 | |
238 | TP_fast_assign( |
239 | __assign_str(device, dev_name(dev)); |
240 | __assign_str(driver, dev_driver_string(dev)); |
241 | __entry->error = error; |
242 | ), |
243 | |
244 | TP_printk("%s %s, err=%d" , |
245 | __get_str(driver), __get_str(device), __entry->error) |
246 | ); |
247 | |
248 | TRACE_EVENT(suspend_resume, |
249 | |
250 | TP_PROTO(const char *action, int val, bool start), |
251 | |
252 | TP_ARGS(action, val, start), |
253 | |
254 | TP_STRUCT__entry( |
255 | __field(const char *, action) |
256 | __field(int, val) |
257 | __field(bool, start) |
258 | ), |
259 | |
260 | TP_fast_assign( |
261 | __entry->action = action; |
262 | __entry->val = val; |
263 | __entry->start = start; |
264 | ), |
265 | |
266 | TP_printk("%s[%u] %s" , __entry->action, (unsigned int)__entry->val, |
267 | (__entry->start)?"begin" :"end" ) |
268 | ); |
269 | |
270 | DECLARE_EVENT_CLASS(wakeup_source, |
271 | |
272 | TP_PROTO(const char *name, unsigned int state), |
273 | |
274 | TP_ARGS(name, state), |
275 | |
276 | TP_STRUCT__entry( |
277 | __string( name, name ) |
278 | __field( u64, state ) |
279 | ), |
280 | |
281 | TP_fast_assign( |
282 | __assign_str(name, name); |
283 | __entry->state = state; |
284 | ), |
285 | |
286 | TP_printk("%s state=0x%lx" , __get_str(name), |
287 | (unsigned long)__entry->state) |
288 | ); |
289 | |
290 | DEFINE_EVENT(wakeup_source, wakeup_source_activate, |
291 | |
292 | TP_PROTO(const char *name, unsigned int state), |
293 | |
294 | TP_ARGS(name, state) |
295 | ); |
296 | |
297 | DEFINE_EVENT(wakeup_source, wakeup_source_deactivate, |
298 | |
299 | TP_PROTO(const char *name, unsigned int state), |
300 | |
301 | TP_ARGS(name, state) |
302 | ); |
303 | |
304 | /* |
305 | * The clock events are used for clock enable/disable and for |
306 | * clock rate change |
307 | */ |
308 | DECLARE_EVENT_CLASS(clock, |
309 | |
310 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), |
311 | |
312 | TP_ARGS(name, state, cpu_id), |
313 | |
314 | TP_STRUCT__entry( |
315 | __string( name, name ) |
316 | __field( u64, state ) |
317 | __field( u64, cpu_id ) |
318 | ), |
319 | |
320 | TP_fast_assign( |
321 | __assign_str(name, name); |
322 | __entry->state = state; |
323 | __entry->cpu_id = cpu_id; |
324 | ), |
325 | |
326 | TP_printk("%s state=%lu cpu_id=%lu" , __get_str(name), |
327 | (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) |
328 | ); |
329 | |
330 | DEFINE_EVENT(clock, clock_enable, |
331 | |
332 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), |
333 | |
334 | TP_ARGS(name, state, cpu_id) |
335 | ); |
336 | |
337 | DEFINE_EVENT(clock, clock_disable, |
338 | |
339 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), |
340 | |
341 | TP_ARGS(name, state, cpu_id) |
342 | ); |
343 | |
344 | DEFINE_EVENT(clock, clock_set_rate, |
345 | |
346 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), |
347 | |
348 | TP_ARGS(name, state, cpu_id) |
349 | ); |
350 | |
351 | /* |
352 | * The power domain events are used for power domains transitions |
353 | */ |
354 | DECLARE_EVENT_CLASS(power_domain, |
355 | |
356 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), |
357 | |
358 | TP_ARGS(name, state, cpu_id), |
359 | |
360 | TP_STRUCT__entry( |
361 | __string( name, name ) |
362 | __field( u64, state ) |
363 | __field( u64, cpu_id ) |
364 | ), |
365 | |
366 | TP_fast_assign( |
367 | __assign_str(name, name); |
368 | __entry->state = state; |
369 | __entry->cpu_id = cpu_id; |
370 | ), |
371 | |
372 | TP_printk("%s state=%lu cpu_id=%lu" , __get_str(name), |
373 | (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) |
374 | ); |
375 | |
376 | DEFINE_EVENT(power_domain, power_domain_target, |
377 | |
378 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), |
379 | |
380 | TP_ARGS(name, state, cpu_id) |
381 | ); |
382 | |
383 | /* |
384 | * CPU latency QoS events used for global CPU latency QoS list updates |
385 | */ |
386 | DECLARE_EVENT_CLASS(cpu_latency_qos_request, |
387 | |
388 | TP_PROTO(s32 value), |
389 | |
390 | TP_ARGS(value), |
391 | |
392 | TP_STRUCT__entry( |
393 | __field( s32, value ) |
394 | ), |
395 | |
396 | TP_fast_assign( |
397 | __entry->value = value; |
398 | ), |
399 | |
400 | TP_printk("CPU_DMA_LATENCY value=%d" , |
401 | __entry->value) |
402 | ); |
403 | |
404 | DEFINE_EVENT(cpu_latency_qos_request, pm_qos_add_request, |
405 | |
406 | TP_PROTO(s32 value), |
407 | |
408 | TP_ARGS(value) |
409 | ); |
410 | |
411 | DEFINE_EVENT(cpu_latency_qos_request, pm_qos_update_request, |
412 | |
413 | TP_PROTO(s32 value), |
414 | |
415 | TP_ARGS(value) |
416 | ); |
417 | |
418 | DEFINE_EVENT(cpu_latency_qos_request, pm_qos_remove_request, |
419 | |
420 | TP_PROTO(s32 value), |
421 | |
422 | TP_ARGS(value) |
423 | ); |
424 | |
425 | /* |
426 | * General PM QoS events used for updates of PM QoS request lists |
427 | */ |
428 | DECLARE_EVENT_CLASS(pm_qos_update, |
429 | |
430 | TP_PROTO(enum pm_qos_req_action action, int prev_value, int curr_value), |
431 | |
432 | TP_ARGS(action, prev_value, curr_value), |
433 | |
434 | TP_STRUCT__entry( |
435 | __field( enum pm_qos_req_action, action ) |
436 | __field( int, prev_value ) |
437 | __field( int, curr_value ) |
438 | ), |
439 | |
440 | TP_fast_assign( |
441 | __entry->action = action; |
442 | __entry->prev_value = prev_value; |
443 | __entry->curr_value = curr_value; |
444 | ), |
445 | |
446 | TP_printk("action=%s prev_value=%d curr_value=%d" , |
447 | __print_symbolic(__entry->action, |
448 | { PM_QOS_ADD_REQ, "ADD_REQ" }, |
449 | { PM_QOS_UPDATE_REQ, "UPDATE_REQ" }, |
450 | { PM_QOS_REMOVE_REQ, "REMOVE_REQ" }), |
451 | __entry->prev_value, __entry->curr_value) |
452 | ); |
453 | |
454 | DEFINE_EVENT(pm_qos_update, pm_qos_update_target, |
455 | |
456 | TP_PROTO(enum pm_qos_req_action action, int prev_value, int curr_value), |
457 | |
458 | TP_ARGS(action, prev_value, curr_value) |
459 | ); |
460 | |
461 | DEFINE_EVENT_PRINT(pm_qos_update, pm_qos_update_flags, |
462 | |
463 | TP_PROTO(enum pm_qos_req_action action, int prev_value, int curr_value), |
464 | |
465 | TP_ARGS(action, prev_value, curr_value), |
466 | |
467 | TP_printk("action=%s prev_value=0x%x curr_value=0x%x" , |
468 | __print_symbolic(__entry->action, |
469 | { PM_QOS_ADD_REQ, "ADD_REQ" }, |
470 | { PM_QOS_UPDATE_REQ, "UPDATE_REQ" }, |
471 | { PM_QOS_REMOVE_REQ, "REMOVE_REQ" }), |
472 | __entry->prev_value, __entry->curr_value) |
473 | ); |
474 | |
475 | DECLARE_EVENT_CLASS(dev_pm_qos_request, |
476 | |
477 | TP_PROTO(const char *name, enum dev_pm_qos_req_type type, |
478 | s32 new_value), |
479 | |
480 | TP_ARGS(name, type, new_value), |
481 | |
482 | TP_STRUCT__entry( |
483 | __string( name, name ) |
484 | __field( enum dev_pm_qos_req_type, type ) |
485 | __field( s32, new_value ) |
486 | ), |
487 | |
488 | TP_fast_assign( |
489 | __assign_str(name, name); |
490 | __entry->type = type; |
491 | __entry->new_value = new_value; |
492 | ), |
493 | |
494 | TP_printk("device=%s type=%s new_value=%d" , |
495 | __get_str(name), |
496 | __print_symbolic(__entry->type, |
497 | { DEV_PM_QOS_RESUME_LATENCY, "DEV_PM_QOS_RESUME_LATENCY" }, |
498 | { DEV_PM_QOS_FLAGS, "DEV_PM_QOS_FLAGS" }), |
499 | __entry->new_value) |
500 | ); |
501 | |
502 | DEFINE_EVENT(dev_pm_qos_request, dev_pm_qos_add_request, |
503 | |
504 | TP_PROTO(const char *name, enum dev_pm_qos_req_type type, |
505 | s32 new_value), |
506 | |
507 | TP_ARGS(name, type, new_value) |
508 | ); |
509 | |
510 | DEFINE_EVENT(dev_pm_qos_request, dev_pm_qos_update_request, |
511 | |
512 | TP_PROTO(const char *name, enum dev_pm_qos_req_type type, |
513 | s32 new_value), |
514 | |
515 | TP_ARGS(name, type, new_value) |
516 | ); |
517 | |
518 | DEFINE_EVENT(dev_pm_qos_request, dev_pm_qos_remove_request, |
519 | |
520 | TP_PROTO(const char *name, enum dev_pm_qos_req_type type, |
521 | s32 new_value), |
522 | |
523 | TP_ARGS(name, type, new_value) |
524 | ); |
525 | |
526 | TRACE_EVENT(guest_halt_poll_ns, |
527 | |
528 | TP_PROTO(bool grow, unsigned int new, unsigned int old), |
529 | |
530 | TP_ARGS(grow, new, old), |
531 | |
532 | TP_STRUCT__entry( |
533 | __field(bool, grow) |
534 | __field(unsigned int, new) |
535 | __field(unsigned int, old) |
536 | ), |
537 | |
538 | TP_fast_assign( |
539 | __entry->grow = grow; |
540 | __entry->new = new; |
541 | __entry->old = old; |
542 | ), |
543 | |
544 | TP_printk("halt_poll_ns %u (%s %u)" , |
545 | __entry->new, |
546 | __entry->grow ? "grow" : "shrink" , |
547 | __entry->old) |
548 | ); |
549 | |
550 | #define trace_guest_halt_poll_ns_grow(new, old) \ |
551 | trace_guest_halt_poll_ns(true, new, old) |
552 | #define trace_guest_halt_poll_ns_shrink(new, old) \ |
553 | trace_guest_halt_poll_ns(false, new, old) |
554 | #endif /* _TRACE_POWER_H */ |
555 | |
556 | /* This part must be outside protection */ |
557 | #include <trace/define_trace.h> |
558 | |