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