1 /* SPDX-License-Identifier: GPL-2.0 */
2 #undef TRACE_SYSTEM
3 #define TRACE_SYSTEM irq
4 
5 #if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ)
6 #define _TRACE_IRQ_H
7 
8 #include <linux/tracepoint.h>
9 
10 struct irqaction;
11 struct softirq_action;
12 
13 #define SOFTIRQ_NAME_LIST				\
14 			 softirq_name(HI)		\
15 			 softirq_name(TIMER)		\
16 			 softirq_name(NET_TX)		\
17 			 softirq_name(NET_RX)		\
18 			 softirq_name(BLOCK)		\
19 			 softirq_name(IRQ_POLL)		\
20 			 softirq_name(TASKLET)		\
21 			 softirq_name(SCHED)		\
22 			 softirq_name(HRTIMER)		\
23 			 softirq_name_end(RCU)
24 
25 #undef softirq_name
26 #undef softirq_name_end
27 
28 #define softirq_name(sirq) TRACE_DEFINE_ENUM(sirq##_SOFTIRQ);
29 #define softirq_name_end(sirq)  TRACE_DEFINE_ENUM(sirq##_SOFTIRQ);
30 
31 SOFTIRQ_NAME_LIST
32 
33 #undef softirq_name
34 #undef softirq_name_end
35 
36 #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq },
37 #define softirq_name_end(sirq) { sirq##_SOFTIRQ, #sirq }
38 
39 #define show_softirq_name(val)				\
40 	__print_symbolic(val, SOFTIRQ_NAME_LIST)
41 
42 /**
43  * irq_handler_entry - called immediately before the irq action handler
44  * @irq: irq number
45  * @action: pointer to struct irqaction
46  *
47  * The struct irqaction pointed to by @action contains various
48  * information about the handler, including the device name,
49  * @action->name, and the device id, @action->dev_id. When used in
50  * conjunction with the irq_handler_exit tracepoint, we can figure
51  * out irq handler latencies.
52  */
53 TRACE_EVENT(irq_handler_entry,
54 
55 	TP_PROTO(int irq, struct irqaction *action),
56 
57 	TP_ARGS(irq, action),
58 
59 	TP_STRUCT__entry(
60 		__field(	int,	irq		)
61 		__string(	name,	action->name	)
62 	),
63 
64 	TP_fast_assign(
65 		__entry->irq = irq;
66 		__assign_str(name, action->name);
67 	),
68 
69 	TP_printk("irq=%d name=%s", __entry->irq, __get_str(name))
70 );
71 
72 /**
73  * irq_handler_exit - called immediately after the irq action handler returns
74  * @irq: irq number
75  * @action: pointer to struct irqaction
76  * @ret: return value
77  *
78  * If the @ret value is set to IRQ_HANDLED, then we know that the corresponding
79  * @action->handler successfully handled this irq. Otherwise, the irq might be
80  * a shared irq line, or the irq was not handled successfully. Can be used in
81  * conjunction with the irq_handler_entry to understand irq handler latencies.
82  */
83 TRACE_EVENT(irq_handler_exit,
84 
85 	TP_PROTO(int irq, struct irqaction *action, int ret),
86 
87 	TP_ARGS(irq, action, ret),
88 
89 	TP_STRUCT__entry(
90 		__field(	int,	irq	)
91 		__field(	int,	ret	)
92 	),
93 
94 	TP_fast_assign(
95 		__entry->irq	= irq;
96 		__entry->ret	= ret;
97 	),
98 
99 	TP_printk("irq=%d ret=%s",
100 		  __entry->irq, __entry->ret ? "handled" : "unhandled")
101 );
102 
103 DECLARE_EVENT_CLASS(softirq,
104 
105 	TP_PROTO(unsigned int vec_nr),
106 
107 	TP_ARGS(vec_nr),
108 
109 	TP_STRUCT__entry(
110 		__field(	unsigned int,	vec	)
111 	),
112 
113 	TP_fast_assign(
114 		__entry->vec = vec_nr;
115 	),
116 
117 	TP_printk("vec=%u [action=%s]", __entry->vec,
118 		  show_softirq_name(__entry->vec))
119 );
120 
121 /**
122  * softirq_entry - called immediately before the softirq handler
123  * @vec_nr:  softirq vector number
124  *
125  * When used in combination with the softirq_exit tracepoint
126  * we can determine the softirq handler routine.
127  */
128 DEFINE_EVENT(softirq, softirq_entry,
129 
130 	TP_PROTO(unsigned int vec_nr),
131 
132 	TP_ARGS(vec_nr)
133 );
134 
135 /**
136  * softirq_exit - called immediately after the softirq handler returns
137  * @vec_nr:  softirq vector number
138  *
139  * When used in combination with the softirq_entry tracepoint
140  * we can determine the softirq handler routine.
141  */
142 DEFINE_EVENT(softirq, softirq_exit,
143 
144 	TP_PROTO(unsigned int vec_nr),
145 
146 	TP_ARGS(vec_nr)
147 );
148 
149 /**
150  * softirq_raise - called immediately when a softirq is raised
151  * @vec_nr:  softirq vector number
152  *
153  * When used in combination with the softirq_entry tracepoint
154  * we can determine the softirq raise to run latency.
155  */
156 DEFINE_EVENT(softirq, softirq_raise,
157 
158 	TP_PROTO(unsigned int vec_nr),
159 
160 	TP_ARGS(vec_nr)
161 );
162 
163 DECLARE_EVENT_CLASS(tasklet,
164 
165 	TP_PROTO(struct tasklet_struct *t, void *func),
166 
167 	TP_ARGS(t, func),
168 
169 	TP_STRUCT__entry(
170 		__field(	void *,	tasklet)
171 		__field(	void *,	func)
172 	),
173 
174 	TP_fast_assign(
175 		__entry->tasklet = t;
176 		__entry->func = func;
177 	),
178 
179 	TP_printk("tasklet=%ps function=%ps", __entry->tasklet, __entry->func)
180 );
181 
182 /**
183  * tasklet_entry - called immediately before the tasklet is run
184  * @t: tasklet pointer
185  * @func: tasklet callback or function being run
186  *
187  * Used to find individual tasklet execution time
188  */
189 DEFINE_EVENT(tasklet, tasklet_entry,
190 
191 	TP_PROTO(struct tasklet_struct *t, void *func),
192 
193 	TP_ARGS(t, func)
194 );
195 
196 /**
197  * tasklet_exit - called immediately after the tasklet is run
198  * @t: tasklet pointer
199  * @func: tasklet callback or function being run
200  *
201  * Used to find individual tasklet execution time
202  */
203 DEFINE_EVENT(tasklet, tasklet_exit,
204 
205 	TP_PROTO(struct tasklet_struct *t, void *func),
206 
207 	TP_ARGS(t, func)
208 );
209 
210 #endif /*  _TRACE_IRQ_H */
211 
212 /* This part must be outside protection */
213 #include <trace/define_trace.h>
214