xref: /openbmc/linux/include/trace/events/io_uring.h (revision 94d964e5)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #undef TRACE_SYSTEM
3 #define TRACE_SYSTEM io_uring
4 
5 #if !defined(_TRACE_IO_URING_H) || defined(TRACE_HEADER_MULTI_READ)
6 #define _TRACE_IO_URING_H
7 
8 #include <linux/tracepoint.h>
9 #include <uapi/linux/io_uring.h>
10 
11 struct io_wq_work;
12 
13 /**
14  * io_uring_create - called after a new io_uring context was prepared
15  *
16  * @fd:		corresponding file descriptor
17  * @ctx:	pointer to a ring context structure
18  * @sq_entries:	actual SQ size
19  * @cq_entries:	actual CQ size
20  * @flags:	SQ ring flags, provided to io_uring_setup(2)
21  *
22  * Allows to trace io_uring creation and provide pointer to a context, that can
23  * be used later to find correlated events.
24  */
25 TRACE_EVENT(io_uring_create,
26 
27 	TP_PROTO(int fd, void *ctx, u32 sq_entries, u32 cq_entries, u32 flags),
28 
29 	TP_ARGS(fd, ctx, sq_entries, cq_entries, flags),
30 
31 	TP_STRUCT__entry (
32 		__field(  int,		fd			)
33 		__field(  void *,	ctx			)
34 		__field(  u32,		sq_entries	)
35 		__field(  u32,		cq_entries	)
36 		__field(  u32,		flags		)
37 	),
38 
39 	TP_fast_assign(
40 		__entry->fd			= fd;
41 		__entry->ctx		= ctx;
42 		__entry->sq_entries	= sq_entries;
43 		__entry->cq_entries	= cq_entries;
44 		__entry->flags		= flags;
45 	),
46 
47 	TP_printk("ring %p, fd %d sq size %d, cq size %d, flags %d",
48 			  __entry->ctx, __entry->fd, __entry->sq_entries,
49 			  __entry->cq_entries, __entry->flags)
50 );
51 
52 /**
53  * io_uring_register - called after a buffer/file/eventfd was successfully
54  * 					   registered for a ring
55  *
56  * @ctx:		pointer to a ring context structure
57  * @opcode:		describes which operation to perform
58  * @nr_user_files:	number of registered files
59  * @nr_user_bufs:	number of registered buffers
60  * @cq_ev_fd:		whether eventfs registered or not
61  * @ret:		return code
62  *
63  * Allows to trace fixed files/buffers/eventfds, that could be registered to
64  * avoid an overhead of getting references to them for every operation. This
65  * event, together with io_uring_file_get, can provide a full picture of how
66  * much overhead one can reduce via fixing.
67  */
68 TRACE_EVENT(io_uring_register,
69 
70 	TP_PROTO(void *ctx, unsigned opcode, unsigned nr_files,
71 			 unsigned nr_bufs, bool eventfd, long ret),
72 
73 	TP_ARGS(ctx, opcode, nr_files, nr_bufs, eventfd, ret),
74 
75 	TP_STRUCT__entry (
76 		__field(  void *,	ctx			)
77 		__field(  unsigned,	opcode		)
78 		__field(  unsigned,	nr_files	)
79 		__field(  unsigned,	nr_bufs		)
80 		__field(  bool,		eventfd		)
81 		__field(  long,		ret			)
82 	),
83 
84 	TP_fast_assign(
85 		__entry->ctx		= ctx;
86 		__entry->opcode		= opcode;
87 		__entry->nr_files	= nr_files;
88 		__entry->nr_bufs	= nr_bufs;
89 		__entry->eventfd	= eventfd;
90 		__entry->ret		= ret;
91 	),
92 
93 	TP_printk("ring %p, opcode %d, nr_user_files %d, nr_user_bufs %d, "
94 			  "eventfd %d, ret %ld",
95 			  __entry->ctx, __entry->opcode, __entry->nr_files,
96 			  __entry->nr_bufs, __entry->eventfd, __entry->ret)
97 );
98 
99 /**
100  * io_uring_file_get - called before getting references to an SQE file
101  *
102  * @ctx:	pointer to a ring context structure
103  * @fd:		SQE file descriptor
104  *
105  * Allows to trace out how often an SQE file reference is obtained, which can
106  * help figuring out if it makes sense to use fixed files, or check that fixed
107  * files are used correctly.
108  */
109 TRACE_EVENT(io_uring_file_get,
110 
111 	TP_PROTO(void *ctx, int fd),
112 
113 	TP_ARGS(ctx, fd),
114 
115 	TP_STRUCT__entry (
116 		__field(  void *,	ctx	)
117 		__field(  int,		fd	)
118 	),
119 
120 	TP_fast_assign(
121 		__entry->ctx	= ctx;
122 		__entry->fd		= fd;
123 	),
124 
125 	TP_printk("ring %p, fd %d", __entry->ctx, __entry->fd)
126 );
127 
128 /**
129  * io_uring_queue_async_work - called before submitting a new async work
130  *
131  * @ctx:	pointer to a ring context structure
132  * @hashed:	type of workqueue, hashed or normal
133  * @req:	pointer to a submitted request
134  * @work:	pointer to a submitted io_wq_work
135  *
136  * Allows to trace asynchronous work submission.
137  */
138 TRACE_EVENT(io_uring_queue_async_work,
139 
140 	TP_PROTO(void *ctx, int rw, void * req, struct io_wq_work *work,
141 			 unsigned int flags),
142 
143 	TP_ARGS(ctx, rw, req, work, flags),
144 
145 	TP_STRUCT__entry (
146 		__field(  void *,			ctx	)
147 		__field(  int,				rw	)
148 		__field(  void *,			req	)
149 		__field(  struct io_wq_work *,		work	)
150 		__field(  unsigned int,			flags	)
151 	),
152 
153 	TP_fast_assign(
154 		__entry->ctx	= ctx;
155 		__entry->rw	= rw;
156 		__entry->req	= req;
157 		__entry->work	= work;
158 		__entry->flags	= flags;
159 	),
160 
161 	TP_printk("ring %p, request %p, flags %d, %s queue, work %p",
162 			  __entry->ctx, __entry->req, __entry->flags,
163 			  __entry->rw ? "hashed" : "normal", __entry->work)
164 );
165 
166 /**
167  * io_uring_defer - called when an io_uring request is deferred
168  *
169  * @ctx:	pointer to a ring context structure
170  * @req:	pointer to a deferred request
171  * @user_data:	user data associated with the request
172  *
173  * Allows to track deferred requests, to get an insight about what requests are
174  * not started immediately.
175  */
176 TRACE_EVENT(io_uring_defer,
177 
178 	TP_PROTO(void *ctx, void *req, unsigned long long user_data),
179 
180 	TP_ARGS(ctx, req, user_data),
181 
182 	TP_STRUCT__entry (
183 		__field(  void *,	ctx		)
184 		__field(  void *,	req		)
185 		__field(  unsigned long long, data	)
186 	),
187 
188 	TP_fast_assign(
189 		__entry->ctx	= ctx;
190 		__entry->req	= req;
191 		__entry->data	= user_data;
192 	),
193 
194 	TP_printk("ring %p, request %p user_data %llu", __entry->ctx,
195 			__entry->req, __entry->data)
196 );
197 
198 /**
199  * io_uring_link - called before the io_uring request added into link_list of
200  * 		   another request
201  *
202  * @ctx:		pointer to a ring context structure
203  * @req:		pointer to a linked request
204  * @target_req:		pointer to a previous request, that would contain @req
205  *
206  * Allows to track linked requests, to understand dependencies between requests
207  * and how does it influence their execution flow.
208  */
209 TRACE_EVENT(io_uring_link,
210 
211 	TP_PROTO(void *ctx, void *req, void *target_req),
212 
213 	TP_ARGS(ctx, req, target_req),
214 
215 	TP_STRUCT__entry (
216 		__field(  void *,	ctx		)
217 		__field(  void *,	req		)
218 		__field(  void *,	target_req	)
219 	),
220 
221 	TP_fast_assign(
222 		__entry->ctx		= ctx;
223 		__entry->req		= req;
224 		__entry->target_req	= target_req;
225 	),
226 
227 	TP_printk("ring %p, request %p linked after %p",
228 			  __entry->ctx, __entry->req, __entry->target_req)
229 );
230 
231 /**
232  * io_uring_cqring_wait - called before start waiting for an available CQE
233  *
234  * @ctx:		pointer to a ring context structure
235  * @min_events:	minimal number of events to wait for
236  *
237  * Allows to track waiting for CQE, so that we can e.g. troubleshoot
238  * situations, when an application wants to wait for an event, that never
239  * comes.
240  */
241 TRACE_EVENT(io_uring_cqring_wait,
242 
243 	TP_PROTO(void *ctx, int min_events),
244 
245 	TP_ARGS(ctx, min_events),
246 
247 	TP_STRUCT__entry (
248 		__field(  void *,	ctx		)
249 		__field(  int,		min_events	)
250 	),
251 
252 	TP_fast_assign(
253 		__entry->ctx	= ctx;
254 		__entry->min_events	= min_events;
255 	),
256 
257 	TP_printk("ring %p, min_events %d", __entry->ctx, __entry->min_events)
258 );
259 
260 /**
261  * io_uring_fail_link - called before failing a linked request
262  *
263  * @req:	request, which links were cancelled
264  * @link:	cancelled link
265  *
266  * Allows to track linked requests cancellation, to see not only that some work
267  * was cancelled, but also which request was the reason.
268  */
269 TRACE_EVENT(io_uring_fail_link,
270 
271 	TP_PROTO(void *req, void *link),
272 
273 	TP_ARGS(req, link),
274 
275 	TP_STRUCT__entry (
276 		__field(  void *,	req	)
277 		__field(  void *,	link	)
278 	),
279 
280 	TP_fast_assign(
281 		__entry->req	= req;
282 		__entry->link	= link;
283 	),
284 
285 	TP_printk("request %p, link %p", __entry->req, __entry->link)
286 );
287 
288 /**
289  * io_uring_complete - called when completing an SQE
290  *
291  * @ctx:		pointer to a ring context structure
292  * @user_data:		user data associated with the request
293  * @res:		result of the request
294  * @cflags:		completion flags
295  *
296  */
297 TRACE_EVENT(io_uring_complete,
298 
299 	TP_PROTO(void *ctx, u64 user_data, int res, unsigned cflags),
300 
301 	TP_ARGS(ctx, user_data, res, cflags),
302 
303 	TP_STRUCT__entry (
304 		__field(  void *,	ctx		)
305 		__field(  u64,		user_data	)
306 		__field(  int,		res		)
307 		__field(  unsigned,	cflags		)
308 	),
309 
310 	TP_fast_assign(
311 		__entry->ctx		= ctx;
312 		__entry->user_data	= user_data;
313 		__entry->res		= res;
314 		__entry->cflags		= cflags;
315 	),
316 
317 	TP_printk("ring %p, user_data 0x%llx, result %d, cflags %x",
318 			  __entry->ctx, (unsigned long long)__entry->user_data,
319 			  __entry->res, __entry->cflags)
320 );
321 
322 /**
323  * io_uring_submit_sqe - called before submitting one SQE
324  *
325  * @ctx:		pointer to a ring context structure
326  * @req:		pointer to a submitted request
327  * @opcode:		opcode of request
328  * @user_data:		user data associated with the request
329  * @flags		request flags
330  * @force_nonblock:	whether a context blocking or not
331  * @sq_thread:		true if sq_thread has submitted this SQE
332  *
333  * Allows to track SQE submitting, to understand what was the source of it, SQ
334  * thread or io_uring_enter call.
335  */
336 TRACE_EVENT(io_uring_submit_sqe,
337 
338 	TP_PROTO(void *ctx, void *req, u8 opcode, u64 user_data, u32 flags,
339 		 bool force_nonblock, bool sq_thread),
340 
341 	TP_ARGS(ctx, req, opcode, user_data, flags, force_nonblock, sq_thread),
342 
343 	TP_STRUCT__entry (
344 		__field(  void *,	ctx		)
345 		__field(  void *,	req		)
346 		__field(  u8,		opcode		)
347 		__field(  u64,		user_data	)
348 		__field(  u32,		flags		)
349 		__field(  bool,		force_nonblock	)
350 		__field(  bool,		sq_thread	)
351 	),
352 
353 	TP_fast_assign(
354 		__entry->ctx		= ctx;
355 		__entry->req		= req;
356 		__entry->opcode		= opcode;
357 		__entry->user_data	= user_data;
358 		__entry->flags		= flags;
359 		__entry->force_nonblock	= force_nonblock;
360 		__entry->sq_thread	= sq_thread;
361 	),
362 
363 	TP_printk("ring %p, req %p, op %d, data 0x%llx, flags %u, "
364 		  "non block %d, sq_thread %d", __entry->ctx, __entry->req,
365 		  __entry->opcode, (unsigned long long)__entry->user_data,
366 		  __entry->flags, __entry->force_nonblock, __entry->sq_thread)
367 );
368 
369 /*
370  * io_uring_poll_arm - called after arming a poll wait if successful
371  *
372  * @ctx:		pointer to a ring context structure
373  * @req:		pointer to the armed request
374  * @opcode:		opcode of request
375  * @user_data:		user data associated with the request
376  * @mask:		request poll events mask
377  * @events:		registered events of interest
378  *
379  * Allows to track which fds are waiting for and what are the events of
380  * interest.
381  */
382 TRACE_EVENT(io_uring_poll_arm,
383 
384 	TP_PROTO(void *ctx, void *req, u8 opcode, u64 user_data,
385 		 int mask, int events),
386 
387 	TP_ARGS(ctx, req, opcode, user_data, mask, events),
388 
389 	TP_STRUCT__entry (
390 		__field(  void *,	ctx		)
391 		__field(  void *,	req		)
392 		__field(  u8,		opcode		)
393 		__field(  u64,		user_data	)
394 		__field(  int,		mask		)
395 		__field(  int,		events		)
396 	),
397 
398 	TP_fast_assign(
399 		__entry->ctx		= ctx;
400 		__entry->req		= req;
401 		__entry->opcode		= opcode;
402 		__entry->user_data	= user_data;
403 		__entry->mask		= mask;
404 		__entry->events		= events;
405 	),
406 
407 	TP_printk("ring %p, req %p, op %d, data 0x%llx, mask 0x%x, events 0x%x",
408 		  __entry->ctx, __entry->req, __entry->opcode,
409 		  (unsigned long long) __entry->user_data,
410 		  __entry->mask, __entry->events)
411 );
412 
413 TRACE_EVENT(io_uring_poll_wake,
414 
415 	TP_PROTO(void *ctx, u8 opcode, u64 user_data, int mask),
416 
417 	TP_ARGS(ctx, opcode, user_data, mask),
418 
419 	TP_STRUCT__entry (
420 		__field(  void *,	ctx		)
421 		__field(  u8,		opcode		)
422 		__field(  u64,		user_data	)
423 		__field(  int,		mask		)
424 	),
425 
426 	TP_fast_assign(
427 		__entry->ctx		= ctx;
428 		__entry->opcode		= opcode;
429 		__entry->user_data	= user_data;
430 		__entry->mask		= mask;
431 	),
432 
433 	TP_printk("ring %p, op %d, data 0x%llx, mask 0x%x",
434 			  __entry->ctx, __entry->opcode,
435 			  (unsigned long long) __entry->user_data,
436 			  __entry->mask)
437 );
438 
439 TRACE_EVENT(io_uring_task_add,
440 
441 	TP_PROTO(void *ctx, u8 opcode, u64 user_data, int mask),
442 
443 	TP_ARGS(ctx, opcode, user_data, mask),
444 
445 	TP_STRUCT__entry (
446 		__field(  void *,	ctx		)
447 		__field(  u8,		opcode		)
448 		__field(  u64,		user_data	)
449 		__field(  int,		mask		)
450 	),
451 
452 	TP_fast_assign(
453 		__entry->ctx		= ctx;
454 		__entry->opcode		= opcode;
455 		__entry->user_data	= user_data;
456 		__entry->mask		= mask;
457 	),
458 
459 	TP_printk("ring %p, op %d, data 0x%llx, mask %x",
460 			  __entry->ctx, __entry->opcode,
461 			  (unsigned long long) __entry->user_data,
462 			  __entry->mask)
463 );
464 
465 /*
466  * io_uring_task_run - called when task_work_run() executes the poll events
467  *                     notification callbacks
468  *
469  * @ctx:		pointer to a ring context structure
470  * @req:		pointer to the armed request
471  * @opcode:		opcode of request
472  * @user_data:		user data associated with the request
473  *
474  * Allows to track when notified poll events are processed
475  */
476 TRACE_EVENT(io_uring_task_run,
477 
478 	TP_PROTO(void *ctx, void *req, u8 opcode, u64 user_data),
479 
480 	TP_ARGS(ctx, req, opcode, user_data),
481 
482 	TP_STRUCT__entry (
483 		__field(  void *,	ctx		)
484 		__field(  void *,	req		)
485 		__field(  u8,		opcode		)
486 		__field(  u64,		user_data	)
487 	),
488 
489 	TP_fast_assign(
490 		__entry->ctx		= ctx;
491 		__entry->req		= req;
492 		__entry->opcode		= opcode;
493 		__entry->user_data	= user_data;
494 	),
495 
496 	TP_printk("ring %p, req %p, op %d, data 0x%llx",
497 		  __entry->ctx, __entry->req, __entry->opcode,
498 		  (unsigned long long) __entry->user_data)
499 );
500 
501 /*
502  * io_uring_req_failed - called when an sqe is errored dring submission
503  *
504  * @sqe:		pointer to the io_uring_sqe that failed
505  * @error:		error it failed with
506  *
507  * Allows easier diagnosing of malformed requests in production systems.
508  */
509 TRACE_EVENT(io_uring_req_failed,
510 
511 	TP_PROTO(const struct io_uring_sqe *sqe, int error),
512 
513 	TP_ARGS(sqe, error),
514 
515 	TP_STRUCT__entry (
516 		__field(  u8,	opcode )
517 		__field(  u8,	flags )
518 		__field(  u8,	ioprio )
519 		__field( u64,	off )
520 		__field( u64,	addr )
521 		__field( u32,	len )
522 		__field( u32,	op_flags )
523 		__field( u64,	user_data )
524 		__field( u16,	buf_index )
525 		__field( u16,	personality )
526 		__field( u32,	file_index )
527 		__field( u64,	pad1 )
528 		__field( u64,	pad2 )
529 		__field( int,	error )
530 	),
531 
532 	TP_fast_assign(
533 		__entry->opcode		= sqe->opcode;
534 		__entry->flags		= sqe->flags;
535 		__entry->ioprio		= sqe->ioprio;
536 		__entry->off		= sqe->off;
537 		__entry->addr		= sqe->addr;
538 		__entry->len		= sqe->len;
539 		__entry->op_flags	= sqe->rw_flags;
540 		__entry->user_data	= sqe->user_data;
541 		__entry->buf_index	= sqe->buf_index;
542 		__entry->personality	= sqe->personality;
543 		__entry->file_index	= sqe->file_index;
544 		__entry->pad1		= sqe->__pad2[0];
545 		__entry->pad2		= sqe->__pad2[1];
546 		__entry->error		= error;
547 	),
548 
549 	TP_printk("op %d, flags=0x%x, prio=%d, off=%llu, addr=%llu, "
550 		  "len=%u, rw_flags=0x%x, user_data=0x%llx, buf_index=%d, "
551 		  "personality=%d, file_index=%d, pad=0x%llx/%llx, error=%d",
552 		  __entry->opcode, __entry->flags, __entry->ioprio,
553 		  (unsigned long long)__entry->off,
554 		  (unsigned long long) __entry->addr, __entry->len,
555 		  __entry->op_flags, (unsigned long long) __entry->user_data,
556 		  __entry->buf_index, __entry->personality, __entry->file_index,
557 		  (unsigned long long) __entry->pad1,
558 		  (unsigned long long) __entry->pad2, __entry->error)
559 );
560 
561 #endif /* _TRACE_IO_URING_H */
562 
563 /* This part must be outside protection */
564 #include <trace/define_trace.h>
565