xref: /linux/include/trace/events/workqueue.h (revision 8bbd858c4710ff90491365c09209d9d6f70ced77)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #undef TRACE_SYSTEM
3 #define TRACE_SYSTEM workqueue
4 
5 #if !defined(_TRACE_WORKQUEUE_H) || defined(TRACE_HEADER_MULTI_READ)
6 #define _TRACE_WORKQUEUE_H
7 
8 #include <linux/tracepoint.h>
9 #include <linux/workqueue.h>
10 
11 struct pool_workqueue;
12 struct worker_pool;
13 
14 /**
15  * workqueue_queue_work - called when a work gets queued
16  * @req_cpu:	the requested cpu
17  * @pwq:	pointer to struct pool_workqueue
18  * @work:	pointer to struct work_struct
19  *
20  * This event occurs when a work is queued immediately or once a
21  * delayed work is actually queued on a workqueue (ie: once the delay
22  * has been reached).
23  */
24 TRACE_EVENT(workqueue_queue_work,
25 
26 	TP_PROTO(int req_cpu, struct pool_workqueue *pwq,
27 		 struct work_struct *work),
28 
29 	TP_ARGS(req_cpu, pwq, work),
30 
31 	TP_STRUCT__entry(
32 		__field( void *,	work	)
33 		__field( void *,	function)
34 		__string( workqueue,	pwq->wq->name)
35 		__field( int,	req_cpu	)
36 		__field( int,	cpu	)
37 	),
38 
39 	TP_fast_assign(
40 		__entry->work		= work;
41 		__entry->function	= work->func;
42 		__assign_str(workqueue);
43 		__entry->req_cpu	= req_cpu;
44 		__entry->cpu		= pwq->pool->cpu;
45 	),
46 
47 	TP_printk("work struct=%p function=%ps workqueue=%s req_cpu=%d cpu=%d",
48 		  __entry->work, __entry->function, __get_str(workqueue),
49 		  __entry->req_cpu, __entry->cpu)
50 );
51 
52 /**
53  * workqueue_activate_work - called when a work gets activated
54  * @work:	pointer to struct work_struct
55  *
56  * This event occurs when a queued work is put on the active queue,
57  * which happens immediately after queueing unless @max_active limit
58  * is reached.
59  */
60 TRACE_EVENT(workqueue_activate_work,
61 
62 	TP_PROTO(struct work_struct *work),
63 
64 	TP_ARGS(work),
65 
66 	TP_STRUCT__entry(
67 		__field( void *,	work	)
68 		__field( void *,	function)
69 	),
70 
71 	TP_fast_assign(
72 		__entry->work		= work;
73 		__entry->function	= work->func;
74 	),
75 
76 	TP_printk("work struct %p function=%ps ", __entry->work, __entry->function)
77 );
78 
79 /**
80  * workqueue_execute_start - called immediately before the workqueue callback
81  * @work:	pointer to struct work_struct
82  *
83  * Allows to track workqueue execution.
84  */
85 TRACE_EVENT(workqueue_execute_start,
86 
87 	TP_PROTO(struct work_struct *work),
88 
89 	TP_ARGS(work),
90 
91 	TP_STRUCT__entry(
92 		__field( void *,	work	)
93 		__field( void *,	function)
94 	),
95 
96 	TP_fast_assign(
97 		__entry->work		= work;
98 		__entry->function	= work->func;
99 	),
100 
101 	TP_printk("work struct %p: function %ps", __entry->work, __entry->function)
102 );
103 
104 /**
105  * workqueue_execute_end - called immediately after the workqueue callback
106  * @work:	pointer to struct work_struct
107  * @function:   pointer to worker function
108  *
109  * Allows to track workqueue execution.
110  */
111 TRACE_EVENT(workqueue_execute_end,
112 
113 	TP_PROTO(struct work_struct *work, work_func_t function),
114 
115 	TP_ARGS(work, function),
116 
117 	TP_STRUCT__entry(
118 		__field( void *,	work	)
119 		__field( void *,	function)
120 	),
121 
122 	TP_fast_assign(
123 		__entry->work		= work;
124 		__entry->function	= function;
125 	),
126 
127 	TP_printk("work struct %p: function %ps", __entry->work, __entry->function)
128 );
129 
130 /**
131  * workqueue_cpu_intensive - called when a work item exceeds cpu_intensive threshold
132  * @pwq:	pointer to struct pool_workqueue
133  * @work:	pointer to struct work_struct
134  * @function:	pointer to worker function
135  * @duration_us: CPU time consumed in microseconds
136  *
137  * This event occurs when a concurrency-managed work item runs for longer
138  * than wq_cpu_intensive_thresh_us without sleeping and is excluded from
139  * concurrency management to prevent stalling other work items.
140  */
141 TRACE_EVENT(workqueue_cpu_intensive,
142 
143 	TP_PROTO(struct pool_workqueue *pwq, struct work_struct *work,
144 		 work_func_t function, u64 duration_us),
145 
146 	TP_ARGS(pwq, work, function, duration_us),
147 
148 	TP_STRUCT__entry(
149 		__field( void *,	work		)
150 		__field( void *,	function	)
151 		__string( workqueue,	pwq->wq->name	)
152 		__field( int,		cpu		)
153 		__field( u64,		duration_us	)
154 	),
155 
156 	TP_fast_assign(
157 		__entry->work		= work;
158 		__entry->function	= function;
159 		__assign_str(workqueue);
160 		__entry->cpu		= pwq->pool->cpu;
161 		__entry->duration_us	= duration_us;
162 	),
163 
164 	TP_printk("work struct=%p function=%ps workqueue=%s cpu=%d duration_us=%llu",
165 		  __entry->work, __entry->function, __get_str(workqueue),
166 		  __entry->cpu, __entry->duration_us)
167 );
168 
169 /**
170  * workqueue_mayday - called when a pool_workqueue sends mayday to rescuer
171  * @pwq:	pointer to struct pool_workqueue
172  *
173  * This event occurs when a worker pool fails to create a new worker and
174  * requests the workqueue's rescuer thread to process pending works.
175  */
176 TRACE_EVENT(workqueue_mayday,
177 
178 	TP_PROTO(struct pool_workqueue *pwq),
179 
180 	TP_ARGS(pwq),
181 
182 	TP_STRUCT__entry(
183 		__string( workqueue,	pwq->wq->name	)
184 		__field( int,		pool_id		)
185 		__field( int,		cpu		)
186 		__field( int,		nr_active	)
187 	),
188 
189 	TP_fast_assign(
190 		__assign_str(workqueue);
191 		__entry->pool_id	= pwq->pool->id;
192 		__entry->cpu		= pwq->pool->cpu;
193 		__entry->nr_active	= pwq->nr_active;
194 	),
195 
196 	TP_printk("workqueue=%s pool_id=%d cpu=%d nr_active=%d",
197 		  __get_str(workqueue), __entry->pool_id, __entry->cpu,
198 		  __entry->nr_active)
199 );
200 
201 /**
202  * workqueue_rescued - called when a work item is assigned to a rescuer
203  * @pwq:	pointer to struct pool_workqueue
204  * @work:	pointer to struct work_struct
205  * @function:	pointer to worker function
206  *
207  * This event occurs when a work item is claimed by a rescuer thread
208  * to guarantee forward progress.
209  */
210 TRACE_EVENT(workqueue_rescued,
211 
212 	TP_PROTO(struct pool_workqueue *pwq, struct work_struct *work,
213 		 work_func_t function),
214 
215 	TP_ARGS(pwq, work, function),
216 
217 	TP_STRUCT__entry(
218 		__field( void *,	work		)
219 		__field( void *,	function	)
220 		__string( workqueue,	pwq->wq->name	)
221 		__field( int,		cpu		)
222 	),
223 
224 	TP_fast_assign(
225 		__entry->work		= work;
226 		__entry->function	= function;
227 		__assign_str(workqueue);
228 		__entry->cpu		= pwq->pool->cpu;
229 	),
230 
231 	TP_printk("work struct=%p function=%ps workqueue=%s cpu=%d",
232 		  __entry->work, __entry->function, __get_str(workqueue),
233 		  __entry->cpu)
234 );
235 
236 /**
237  * workqueue_bh_budget_yield - called when a BH worker yields due to budget exhaustion
238  * @pool:	pointer to struct worker_pool
239  * @restarts:	number of restarts executed
240  * @timeout:	whether execution hit the time limit (BH_WORKER_JIFFIES)
241  * @highpri:	whether this is a high-priority BH pool
242  *
243  * This event occurs when a bottom-half (BH) worker pool running in softirq
244  * context exhausts its execution time slice or restart limit and must yield
245  * execution.
246  */
247 TRACE_EVENT(workqueue_bh_budget_yield,
248 
249 	TP_PROTO(struct worker_pool *pool, int restarts, bool timeout, bool highpri),
250 
251 	TP_ARGS(pool, restarts, timeout, highpri),
252 
253 	TP_STRUCT__entry(
254 		__field( int,	pool_id		)
255 		__field( int,	cpu		)
256 		__field( int,	restarts	)
257 		__field( bool,	timeout		)
258 		__field( bool,	highpri		)
259 	),
260 
261 	TP_fast_assign(
262 		__entry->pool_id	= pool->id;
263 		__entry->cpu		= pool->cpu;
264 		__entry->restarts	= restarts;
265 		__entry->timeout	= timeout;
266 		__entry->highpri	= highpri;
267 	),
268 
269 	TP_printk("pool_id=%d cpu=%d restarts=%d timeout=%d highpri=%d",
270 		  __entry->pool_id, __entry->cpu, __entry->restarts,
271 		  __entry->timeout, __entry->highpri)
272 );
273 
274 #endif /*  _TRACE_WORKQUEUE_H */
275 
276 /* This part must be outside protection */
277 #include <trace/define_trace.h>
278 
279