Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #undef TRACE_SYSTEM
0003 #define TRACE_SYSTEM io_uring
0004 
0005 #if !defined(_TRACE_IO_URING_H) || defined(TRACE_HEADER_MULTI_READ)
0006 #define _TRACE_IO_URING_H
0007 
0008 #include <linux/tracepoint.h>
0009 #include <uapi/linux/io_uring.h>
0010 #include <linux/io_uring_types.h>
0011 #include <linux/io_uring.h>
0012 
0013 struct io_wq_work;
0014 
0015 /**
0016  * io_uring_create - called after a new io_uring context was prepared
0017  *
0018  * @fd:     corresponding file descriptor
0019  * @ctx:    pointer to a ring context structure
0020  * @sq_entries: actual SQ size
0021  * @cq_entries: actual CQ size
0022  * @flags:  SQ ring flags, provided to io_uring_setup(2)
0023  *
0024  * Allows to trace io_uring creation and provide pointer to a context, that can
0025  * be used later to find correlated events.
0026  */
0027 TRACE_EVENT(io_uring_create,
0028 
0029     TP_PROTO(int fd, void *ctx, u32 sq_entries, u32 cq_entries, u32 flags),
0030 
0031     TP_ARGS(fd, ctx, sq_entries, cq_entries, flags),
0032 
0033     TP_STRUCT__entry (
0034         __field(  int,      fd      )
0035         __field(  void *,   ctx     )
0036         __field(  u32,      sq_entries  )
0037         __field(  u32,      cq_entries  )
0038         __field(  u32,      flags       )
0039     ),
0040 
0041     TP_fast_assign(
0042         __entry->fd     = fd;
0043         __entry->ctx        = ctx;
0044         __entry->sq_entries = sq_entries;
0045         __entry->cq_entries = cq_entries;
0046         __entry->flags      = flags;
0047     ),
0048 
0049     TP_printk("ring %p, fd %d sq size %d, cq size %d, flags 0x%x",
0050               __entry->ctx, __entry->fd, __entry->sq_entries,
0051               __entry->cq_entries, __entry->flags)
0052 );
0053 
0054 /**
0055  * io_uring_register - called after a buffer/file/eventfd was successfully
0056  *                     registered for a ring
0057  *
0058  * @ctx:        pointer to a ring context structure
0059  * @opcode:     describes which operation to perform
0060  * @nr_user_files:  number of registered files
0061  * @nr_user_bufs:   number of registered buffers
0062  * @ret:        return code
0063  *
0064  * Allows to trace fixed files/buffers, that could be registered to
0065  * avoid an overhead of getting references to them for every operation. This
0066  * event, together with io_uring_file_get, can provide a full picture of how
0067  * much overhead one can reduce via fixing.
0068  */
0069 TRACE_EVENT(io_uring_register,
0070 
0071     TP_PROTO(void *ctx, unsigned opcode, unsigned nr_files,
0072              unsigned nr_bufs, long ret),
0073 
0074     TP_ARGS(ctx, opcode, nr_files, nr_bufs, ret),
0075 
0076     TP_STRUCT__entry (
0077         __field(  void *,   ctx )
0078         __field(  unsigned, opcode  )
0079         __field(  unsigned, nr_files)
0080         __field(  unsigned, nr_bufs )
0081         __field(  long,     ret )
0082     ),
0083 
0084     TP_fast_assign(
0085         __entry->ctx        = ctx;
0086         __entry->opcode     = opcode;
0087         __entry->nr_files   = nr_files;
0088         __entry->nr_bufs    = nr_bufs;
0089         __entry->ret        = ret;
0090     ),
0091 
0092     TP_printk("ring %p, opcode %d, nr_user_files %d, nr_user_bufs %d, "
0093               "ret %ld",
0094               __entry->ctx, __entry->opcode, __entry->nr_files,
0095               __entry->nr_bufs, __entry->ret)
0096 );
0097 
0098 /**
0099  * io_uring_file_get - called before getting references to an SQE file
0100  *
0101  * @req:    pointer to a submitted request
0102  * @fd:     SQE file descriptor
0103  *
0104  * Allows to trace out how often an SQE file reference is obtained, which can
0105  * help figuring out if it makes sense to use fixed files, or check that fixed
0106  * files are used correctly.
0107  */
0108 TRACE_EVENT(io_uring_file_get,
0109 
0110     TP_PROTO(struct io_kiocb *req, int fd),
0111 
0112     TP_ARGS(req, fd),
0113 
0114     TP_STRUCT__entry (
0115         __field(  void *,   ctx     )
0116         __field(  void *,   req     )
0117         __field(  u64,      user_data   )
0118         __field(  int,      fd      )
0119     ),
0120 
0121     TP_fast_assign(
0122         __entry->ctx        = req->ctx;
0123         __entry->req        = req;
0124         __entry->user_data  = req->cqe.user_data;
0125         __entry->fd     = fd;
0126     ),
0127 
0128     TP_printk("ring %p, req %p, user_data 0x%llx, fd %d",
0129         __entry->ctx, __entry->req, __entry->user_data, __entry->fd)
0130 );
0131 
0132 /**
0133  * io_uring_queue_async_work - called before submitting a new async work
0134  *
0135  * @req:    pointer to a submitted request
0136  * @rw:     type of workqueue, hashed or normal
0137  *
0138  * Allows to trace asynchronous work submission.
0139  */
0140 TRACE_EVENT(io_uring_queue_async_work,
0141 
0142     TP_PROTO(struct io_kiocb *req, int rw),
0143 
0144     TP_ARGS(req, rw),
0145 
0146     TP_STRUCT__entry (
0147         __field(  void *,           ctx     )
0148         __field(  void *,           req     )
0149         __field(  u64,              user_data   )
0150         __field(  u8,               opcode      )
0151         __field(  unsigned int,         flags       )
0152         __field(  struct io_wq_work *,      work        )
0153         __field(  int,              rw      )
0154 
0155         __string( op_str, io_uring_get_opcode(req->opcode)  )
0156     ),
0157 
0158     TP_fast_assign(
0159         __entry->ctx        = req->ctx;
0160         __entry->req        = req;
0161         __entry->user_data  = req->cqe.user_data;
0162         __entry->flags      = req->flags;
0163         __entry->opcode     = req->opcode;
0164         __entry->work       = &req->work;
0165         __entry->rw     = rw;
0166 
0167         __assign_str(op_str, io_uring_get_opcode(req->opcode));
0168     ),
0169 
0170     TP_printk("ring %p, request %p, user_data 0x%llx, opcode %s, flags 0x%x, %s queue, work %p",
0171         __entry->ctx, __entry->req, __entry->user_data,
0172         __get_str(op_str),
0173         __entry->flags, __entry->rw ? "hashed" : "normal", __entry->work)
0174 );
0175 
0176 /**
0177  * io_uring_defer - called when an io_uring request is deferred
0178  *
0179  * @req:    pointer to a deferred request
0180  *
0181  * Allows to track deferred requests, to get an insight about what requests are
0182  * not started immediately.
0183  */
0184 TRACE_EVENT(io_uring_defer,
0185 
0186     TP_PROTO(struct io_kiocb *req),
0187 
0188     TP_ARGS(req),
0189 
0190     TP_STRUCT__entry (
0191         __field(  void *,       ctx )
0192         __field(  void *,       req )
0193         __field(  unsigned long long,   data    )
0194         __field(  u8,           opcode  )
0195 
0196         __string( op_str, io_uring_get_opcode(req->opcode) )
0197     ),
0198 
0199     TP_fast_assign(
0200         __entry->ctx    = req->ctx;
0201         __entry->req    = req;
0202         __entry->data   = req->cqe.user_data;
0203         __entry->opcode = req->opcode;
0204 
0205         __assign_str(op_str, io_uring_get_opcode(req->opcode));
0206     ),
0207 
0208     TP_printk("ring %p, request %p, user_data 0x%llx, opcode %s",
0209         __entry->ctx, __entry->req, __entry->data,
0210         __get_str(op_str))
0211 );
0212 
0213 /**
0214  * io_uring_link - called before the io_uring request added into link_list of
0215  *         another request
0216  *
0217  * @req:        pointer to a linked request
0218  * @target_req:     pointer to a previous request, that would contain @req
0219  *
0220  * Allows to track linked requests, to understand dependencies between requests
0221  * and how does it influence their execution flow.
0222  */
0223 TRACE_EVENT(io_uring_link,
0224 
0225     TP_PROTO(struct io_kiocb *req, struct io_kiocb *target_req),
0226 
0227     TP_ARGS(req, target_req),
0228 
0229     TP_STRUCT__entry (
0230         __field(  void *,   ctx     )
0231         __field(  void *,   req     )
0232         __field(  void *,   target_req  )
0233     ),
0234 
0235     TP_fast_assign(
0236         __entry->ctx        = req->ctx;
0237         __entry->req        = req;
0238         __entry->target_req = target_req;
0239     ),
0240 
0241     TP_printk("ring %p, request %p linked after %p",
0242               __entry->ctx, __entry->req, __entry->target_req)
0243 );
0244 
0245 /**
0246  * io_uring_cqring_wait - called before start waiting for an available CQE
0247  *
0248  * @ctx:        pointer to a ring context structure
0249  * @min_events: minimal number of events to wait for
0250  *
0251  * Allows to track waiting for CQE, so that we can e.g. troubleshoot
0252  * situations, when an application wants to wait for an event, that never
0253  * comes.
0254  */
0255 TRACE_EVENT(io_uring_cqring_wait,
0256 
0257     TP_PROTO(void *ctx, int min_events),
0258 
0259     TP_ARGS(ctx, min_events),
0260 
0261     TP_STRUCT__entry (
0262         __field(  void *,   ctx     )
0263         __field(  int,      min_events  )
0264     ),
0265 
0266     TP_fast_assign(
0267         __entry->ctx        = ctx;
0268         __entry->min_events = min_events;
0269     ),
0270 
0271     TP_printk("ring %p, min_events %d", __entry->ctx, __entry->min_events)
0272 );
0273 
0274 /**
0275  * io_uring_fail_link - called before failing a linked request
0276  *
0277  * @req:    request, which links were cancelled
0278  * @link:   cancelled link
0279  *
0280  * Allows to track linked requests cancellation, to see not only that some work
0281  * was cancelled, but also which request was the reason.
0282  */
0283 TRACE_EVENT(io_uring_fail_link,
0284 
0285     TP_PROTO(struct io_kiocb *req, struct io_kiocb *link),
0286 
0287     TP_ARGS(req, link),
0288 
0289     TP_STRUCT__entry (
0290         __field(  void *,       ctx     )
0291         __field(  void *,       req     )
0292         __field(  unsigned long long,   user_data   )
0293         __field(  u8,           opcode      )
0294         __field(  void *,       link        )
0295 
0296         __string( op_str, io_uring_get_opcode(req->opcode) )
0297     ),
0298 
0299     TP_fast_assign(
0300         __entry->ctx        = req->ctx;
0301         __entry->req        = req;
0302         __entry->user_data  = req->cqe.user_data;
0303         __entry->opcode     = req->opcode;
0304         __entry->link       = link;
0305 
0306         __assign_str(op_str, io_uring_get_opcode(req->opcode));
0307     ),
0308 
0309     TP_printk("ring %p, request %p, user_data 0x%llx, opcode %s, link %p",
0310         __entry->ctx, __entry->req, __entry->user_data,
0311         __get_str(op_str), __entry->link)
0312 );
0313 
0314 /**
0315  * io_uring_complete - called when completing an SQE
0316  *
0317  * @ctx:        pointer to a ring context structure
0318  * @req:        pointer to a submitted request
0319  * @user_data:      user data associated with the request
0320  * @res:        result of the request
0321  * @cflags:     completion flags
0322  * @extra1:     extra 64-bit data for CQE32
0323  * @extra2:     extra 64-bit data for CQE32
0324  *
0325  */
0326 TRACE_EVENT(io_uring_complete,
0327 
0328     TP_PROTO(void *ctx, void *req, u64 user_data, int res, unsigned cflags,
0329          u64 extra1, u64 extra2),
0330 
0331     TP_ARGS(ctx, req, user_data, res, cflags, extra1, extra2),
0332 
0333     TP_STRUCT__entry (
0334         __field(  void *,   ctx     )
0335         __field(  void *,   req     )
0336         __field(  u64,      user_data   )
0337         __field(  int,      res     )
0338         __field(  unsigned, cflags      )
0339         __field(  u64,      extra1      )
0340         __field(  u64,      extra2      )
0341     ),
0342 
0343     TP_fast_assign(
0344         __entry->ctx        = ctx;
0345         __entry->req        = req;
0346         __entry->user_data  = user_data;
0347         __entry->res        = res;
0348         __entry->cflags     = cflags;
0349         __entry->extra1     = extra1;
0350         __entry->extra2     = extra2;
0351     ),
0352 
0353     TP_printk("ring %p, req %p, user_data 0x%llx, result %d, cflags 0x%x "
0354           "extra1 %llu extra2 %llu ",
0355         __entry->ctx, __entry->req,
0356         __entry->user_data,
0357         __entry->res, __entry->cflags,
0358         (unsigned long long) __entry->extra1,
0359         (unsigned long long) __entry->extra2)
0360 );
0361 
0362 /**
0363  * io_uring_submit_sqe - called before submitting one SQE
0364  *
0365  * @req:        pointer to a submitted request
0366  * @force_nonblock: whether a context blocking or not
0367  *
0368  * Allows to track SQE submitting, to understand what was the source of it, SQ
0369  * thread or io_uring_enter call.
0370  */
0371 TRACE_EVENT(io_uring_submit_sqe,
0372 
0373     TP_PROTO(struct io_kiocb *req, bool force_nonblock),
0374 
0375     TP_ARGS(req, force_nonblock),
0376 
0377     TP_STRUCT__entry (
0378         __field(  void *,       ctx     )
0379         __field(  void *,       req     )
0380         __field(  unsigned long long,   user_data   )
0381         __field(  u8,           opcode      )
0382         __field(  u32,          flags       )
0383         __field(  bool,         force_nonblock  )
0384         __field(  bool,         sq_thread   )
0385 
0386         __string( op_str, io_uring_get_opcode(req->opcode) )
0387     ),
0388 
0389     TP_fast_assign(
0390         __entry->ctx        = req->ctx;
0391         __entry->req        = req;
0392         __entry->user_data  = req->cqe.user_data;
0393         __entry->opcode     = req->opcode;
0394         __entry->flags      = req->flags;
0395         __entry->force_nonblock = force_nonblock;
0396         __entry->sq_thread  = req->ctx->flags & IORING_SETUP_SQPOLL;
0397 
0398         __assign_str(op_str, io_uring_get_opcode(req->opcode));
0399     ),
0400 
0401     TP_printk("ring %p, req %p, user_data 0x%llx, opcode %s, flags 0x%x, "
0402           "non block %d, sq_thread %d", __entry->ctx, __entry->req,
0403           __entry->user_data, __get_str(op_str),
0404           __entry->flags, __entry->force_nonblock, __entry->sq_thread)
0405 );
0406 
0407 /*
0408  * io_uring_poll_arm - called after arming a poll wait if successful
0409  *
0410  * @req:        pointer to the armed request
0411  * @mask:       request poll events mask
0412  * @events:     registered events of interest
0413  *
0414  * Allows to track which fds are waiting for and what are the events of
0415  * interest.
0416  */
0417 TRACE_EVENT(io_uring_poll_arm,
0418 
0419     TP_PROTO(struct io_kiocb *req, int mask, int events),
0420 
0421     TP_ARGS(req, mask, events),
0422 
0423     TP_STRUCT__entry (
0424         __field(  void *,       ctx     )
0425         __field(  void *,       req     )
0426         __field(  unsigned long long,   user_data   )
0427         __field(  u8,           opcode      )
0428         __field(  int,          mask        )
0429         __field(  int,          events      )
0430 
0431         __string( op_str, io_uring_get_opcode(req->opcode) )
0432     ),
0433 
0434     TP_fast_assign(
0435         __entry->ctx        = req->ctx;
0436         __entry->req        = req;
0437         __entry->user_data  = req->cqe.user_data;
0438         __entry->opcode     = req->opcode;
0439         __entry->mask       = mask;
0440         __entry->events     = events;
0441 
0442         __assign_str(op_str, io_uring_get_opcode(req->opcode));
0443     ),
0444 
0445     TP_printk("ring %p, req %p, user_data 0x%llx, opcode %s, mask 0x%x, events 0x%x",
0446           __entry->ctx, __entry->req, __entry->user_data,
0447           __get_str(op_str),
0448           __entry->mask, __entry->events)
0449 );
0450 
0451 /*
0452  * io_uring_task_add - called after adding a task
0453  *
0454  * @req:        pointer to request
0455  * @mask:       request poll events mask
0456  *
0457  */
0458 TRACE_EVENT(io_uring_task_add,
0459 
0460     TP_PROTO(struct io_kiocb *req, int mask),
0461 
0462     TP_ARGS(req, mask),
0463 
0464     TP_STRUCT__entry (
0465         __field(  void *,       ctx     )
0466         __field(  void *,       req     )
0467         __field(  unsigned long long,   user_data   )
0468         __field(  u8,           opcode      )
0469         __field(  int,          mask        )
0470 
0471         __string( op_str, io_uring_get_opcode(req->opcode) )
0472     ),
0473 
0474     TP_fast_assign(
0475         __entry->ctx        = req->ctx;
0476         __entry->req        = req;
0477         __entry->user_data  = req->cqe.user_data;
0478         __entry->opcode     = req->opcode;
0479         __entry->mask       = mask;
0480 
0481         __assign_str(op_str, io_uring_get_opcode(req->opcode));
0482     ),
0483 
0484     TP_printk("ring %p, req %p, user_data 0x%llx, opcode %s, mask %x",
0485         __entry->ctx, __entry->req, __entry->user_data,
0486         __get_str(op_str),
0487         __entry->mask)
0488 );
0489 
0490 /*
0491  * io_uring_req_failed - called when an sqe is errored dring submission
0492  *
0493  * @sqe:        pointer to the io_uring_sqe that failed
0494  * @req:        pointer to request
0495  * @error:      error it failed with
0496  *
0497  * Allows easier diagnosing of malformed requests in production systems.
0498  */
0499 TRACE_EVENT(io_uring_req_failed,
0500 
0501     TP_PROTO(const struct io_uring_sqe *sqe, struct io_kiocb *req, int error),
0502 
0503     TP_ARGS(sqe, req, error),
0504 
0505     TP_STRUCT__entry (
0506         __field(  void *,       ctx     )
0507         __field(  void *,       req     )
0508         __field(  unsigned long long,   user_data   )
0509         __field(  u8,           opcode      )
0510         __field(  u8,           flags       )
0511         __field(  u8,           ioprio      )
0512         __field( u64,           off     )
0513         __field( u64,           addr        )
0514         __field( u32,           len     )
0515         __field( u32,           op_flags    )
0516         __field( u16,           buf_index   )
0517         __field( u16,           personality )
0518         __field( u32,           file_index  )
0519         __field( u64,           pad1        )
0520         __field( u64,           addr3       )
0521         __field( int,           error       )
0522 
0523         __string( op_str, io_uring_get_opcode(sqe->opcode) )
0524     ),
0525 
0526     TP_fast_assign(
0527         __entry->ctx        = req->ctx;
0528         __entry->req        = req;
0529         __entry->user_data  = sqe->user_data;
0530         __entry->opcode     = sqe->opcode;
0531         __entry->flags      = sqe->flags;
0532         __entry->ioprio     = sqe->ioprio;
0533         __entry->off        = sqe->off;
0534         __entry->addr       = sqe->addr;
0535         __entry->len        = sqe->len;
0536         __entry->op_flags   = sqe->poll32_events;
0537         __entry->buf_index  = sqe->buf_index;
0538         __entry->personality    = sqe->personality;
0539         __entry->file_index = sqe->file_index;
0540         __entry->pad1       = sqe->__pad2[0];
0541         __entry->addr3      = sqe->addr3;
0542         __entry->error      = error;
0543 
0544         __assign_str(op_str, io_uring_get_opcode(sqe->opcode));
0545     ),
0546 
0547     TP_printk("ring %p, req %p, user_data 0x%llx, "
0548           "opcode %s, flags 0x%x, prio=%d, off=%llu, addr=%llu, "
0549           "len=%u, rw_flags=0x%x, buf_index=%d, "
0550           "personality=%d, file_index=%d, pad=0x%llx, addr3=%llx, "
0551           "error=%d",
0552           __entry->ctx, __entry->req, __entry->user_data,
0553           __get_str(op_str),
0554           __entry->flags, __entry->ioprio,
0555           (unsigned long long)__entry->off,
0556           (unsigned long long) __entry->addr, __entry->len,
0557           __entry->op_flags,
0558           __entry->buf_index, __entry->personality, __entry->file_index,
0559           (unsigned long long) __entry->pad1,
0560           (unsigned long long) __entry->addr3, __entry->error)
0561 );
0562 
0563 
0564 /*
0565  * io_uring_cqe_overflow - a CQE overflowed
0566  *
0567  * @ctx:        pointer to a ring context structure
0568  * @user_data:      user data associated with the request
0569  * @res:        CQE result
0570  * @cflags:     CQE flags
0571  * @ocqe:       pointer to the overflow cqe (if available)
0572  *
0573  */
0574 TRACE_EVENT(io_uring_cqe_overflow,
0575 
0576     TP_PROTO(void *ctx, unsigned long long user_data, s32 res, u32 cflags,
0577          void *ocqe),
0578 
0579     TP_ARGS(ctx, user_data, res, cflags, ocqe),
0580 
0581     TP_STRUCT__entry (
0582         __field(  void *,       ctx     )
0583         __field(  unsigned long long,   user_data   )
0584         __field(  s32,          res     )
0585         __field(  u32,          cflags      )
0586         __field(  void *,       ocqe        )
0587     ),
0588 
0589     TP_fast_assign(
0590         __entry->ctx        = ctx;
0591         __entry->user_data  = user_data;
0592         __entry->res        = res;
0593         __entry->cflags     = cflags;
0594         __entry->ocqe       = ocqe;
0595     ),
0596 
0597     TP_printk("ring %p, user_data 0x%llx, res %d, cflags 0x%x, "
0598           "overflow_cqe %p",
0599           __entry->ctx, __entry->user_data, __entry->res,
0600           __entry->cflags, __entry->ocqe)
0601 );
0602 
0603 /*
0604  * io_uring_task_work_run - ran task work
0605  *
0606  * @tctx:       pointer to a io_uring_task
0607  * @count:      how many functions it ran
0608  * @loops:      how many loops it ran
0609  *
0610  */
0611 TRACE_EVENT(io_uring_task_work_run,
0612 
0613     TP_PROTO(void *tctx, unsigned int count, unsigned int loops),
0614 
0615     TP_ARGS(tctx, count, loops),
0616 
0617     TP_STRUCT__entry (
0618         __field(  void *,       tctx        )
0619         __field(  unsigned int,     count       )
0620         __field(  unsigned int,     loops       )
0621     ),
0622 
0623     TP_fast_assign(
0624         __entry->tctx       = tctx;
0625         __entry->count      = count;
0626         __entry->loops      = loops;
0627     ),
0628 
0629     TP_printk("tctx %p, count %u, loops %u",
0630          __entry->tctx, __entry->count, __entry->loops)
0631 );
0632 
0633 TRACE_EVENT(io_uring_short_write,
0634 
0635     TP_PROTO(void *ctx, u64 fpos, u64 wanted, u64 got),
0636 
0637     TP_ARGS(ctx, fpos, wanted, got),
0638 
0639     TP_STRUCT__entry(
0640         __field(void *, ctx)
0641         __field(u64,    fpos)
0642         __field(u64,    wanted)
0643         __field(u64,    got)
0644     ),
0645 
0646     TP_fast_assign(
0647         __entry->ctx    = ctx;
0648         __entry->fpos   = fpos;
0649         __entry->wanted = wanted;
0650         __entry->got    = got;
0651     ),
0652 
0653     TP_printk("ring %p, fpos %lld, wanted %lld, got %lld",
0654               __entry->ctx, __entry->fpos,
0655               __entry->wanted, __entry->got)
0656 );
0657 
0658 #endif /* _TRACE_IO_URING_H */
0659 
0660 /* This part must be outside protection */
0661 #include <trace/define_trace.h>