io_uring.h 8.8 KB
Newer Older
1 2 3 4 5 6 7 8 9
/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM io_uring

#if !defined(_TRACE_IO_URING_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_IO_URING_H

#include <linux/tracepoint.h>

10 11
struct io_wq_work;

12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
/**
 * io_uring_create - called after a new io_uring context was prepared
 *
 * @fd:			corresponding file descriptor
 * @ctx:		pointer to a ring context structure
 * @sq_entries:	actual SQ size
 * @cq_entries:	actual CQ size
 * @flags:		SQ ring flags, provided to io_uring_setup(2)
 *
 * Allows to trace io_uring creation and provide pointer to a context, that can
 * be used later to find correlated events.
 */
TRACE_EVENT(io_uring_create,

	TP_PROTO(int fd, void *ctx, u32 sq_entries, u32 cq_entries, u32 flags),

	TP_ARGS(fd, ctx, sq_entries, cq_entries, flags),

	TP_STRUCT__entry (
		__field(  int,		fd			)
		__field(  void *,	ctx			)
		__field(  u32,		sq_entries	)
		__field(  u32,		cq_entries	)
		__field(  u32,		flags		)
	),

	TP_fast_assign(
		__entry->fd			= fd;
		__entry->ctx		= ctx;
		__entry->sq_entries	= sq_entries;
		__entry->cq_entries	= cq_entries;
		__entry->flags		= flags;
	),

	TP_printk("ring %p, fd %d sq size %d, cq size %d, flags %d",
			  __entry->ctx, __entry->fd, __entry->sq_entries,
			  __entry->cq_entries, __entry->flags)
);

/**
 * io_uring_register - called after a buffer/file/eventfd was succesfully
 * 					   registered for a ring
 *
 * @ctx:			pointer to a ring context structure
 * @opcode:			describes which operation to perform
 * @nr_user_files:	number of registered files
 * @nr_user_bufs:	number of registered buffers
 * @cq_ev_fd:		whether eventfs registered or not
 * @ret:			return code
 *
 * Allows to trace fixed files/buffers/eventfds, that could be registered to
 * avoid an overhead of getting references to them for every operation. This
 * event, together with io_uring_file_get, can provide a full picture of how
 * much overhead one can reduce via fixing.
 */
TRACE_EVENT(io_uring_register,

	TP_PROTO(void *ctx, unsigned opcode, unsigned nr_files,
			 unsigned nr_bufs, bool eventfd, long ret),

	TP_ARGS(ctx, opcode, nr_files, nr_bufs, eventfd, ret),

	TP_STRUCT__entry (
		__field(  void *,	ctx			)
		__field(  unsigned,	opcode		)
		__field(  unsigned,	nr_files	)
		__field(  unsigned,	nr_bufs		)
		__field(  bool,		eventfd		)
		__field(  long,		ret			)
	),

	TP_fast_assign(
		__entry->ctx		= ctx;
		__entry->opcode		= opcode;
		__entry->nr_files	= nr_files;
		__entry->nr_bufs	= nr_bufs;
		__entry->eventfd	= eventfd;
		__entry->ret		= ret;
	),

	TP_printk("ring %p, opcode %d, nr_user_files %d, nr_user_bufs %d, "
			  "eventfd %d, ret %ld",
			  __entry->ctx, __entry->opcode, __entry->nr_files,
			  __entry->nr_bufs, __entry->eventfd, __entry->ret)
);

/**
 * io_uring_file_get - called before getting references to an SQE file
 *
 * @ctx:	pointer to a ring context structure
 * @fd:		SQE file descriptor
 *
 * Allows to trace out how often an SQE file reference is obtained, which can
 * help figuring out if it makes sense to use fixed files, or check that fixed
 * files are used correctly.
 */
TRACE_EVENT(io_uring_file_get,

	TP_PROTO(void *ctx, int fd),

	TP_ARGS(ctx, fd),

	TP_STRUCT__entry (
		__field(  void *,	ctx	)
		__field(  int,		fd	)
	),

	TP_fast_assign(
		__entry->ctx	= ctx;
		__entry->fd		= fd;
	),

	TP_printk("ring %p, fd %d", __entry->ctx, __entry->fd)
);

/**
 * io_uring_queue_async_work - called before submitting a new async work
 *
 * @ctx:	pointer to a ring context structure
131
 * @hashed:	type of workqueue, hashed or normal
132
 * @req:	pointer to a submitted request
133
 * @work:	pointer to a submitted io_wq_work
134 135 136 137 138
 *
 * Allows to trace asynchronous work submission.
 */
TRACE_EVENT(io_uring_queue_async_work,

139
	TP_PROTO(void *ctx, int rw, void * req, struct io_wq_work *work,
140 141 142 143 144 145 146 147
			 unsigned int flags),

	TP_ARGS(ctx, rw, req, work, flags),

	TP_STRUCT__entry (
		__field(  void *,				ctx		)
		__field(  int,					rw		)
		__field(  void *,				req		)
148
		__field(  struct io_wq_work *,		work	)
149 150 151 152 153 154 155 156 157 158 159 160 161
		__field(  unsigned int,			flags	)
	),

	TP_fast_assign(
		__entry->ctx	= ctx;
		__entry->rw		= rw;
		__entry->req	= req;
		__entry->work	= work;
		__entry->flags	= flags;
	),

	TP_printk("ring %p, request %p, flags %d, %s queue, work %p",
			  __entry->ctx, __entry->req, __entry->flags,
162
			  __entry->rw ? "hashed" : "normal", __entry->work)
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
);

/**
 * io_uring_defer_list - called before the io_uring work added into defer_list
 *
 * @ctx:	pointer to a ring context structure
 * @req:	pointer to a deferred request
 * @shadow: whether request is shadow or not
 *
 * Allows to track deferred requests, to get an insight about what requests are
 * not started immediately.
 */
TRACE_EVENT(io_uring_defer,

	TP_PROTO(void *ctx, void *req, bool shadow),

	TP_ARGS(ctx, req, shadow),

	TP_STRUCT__entry (
		__field(  void *,	ctx		)
		__field(  void *,	req		)
		__field(  bool,		shadow	)
	),

	TP_fast_assign(
		__entry->ctx	= ctx;
		__entry->req	= req;
		__entry->shadow	= shadow;
	),

	TP_printk("ring %p, request %p%s", __entry->ctx, __entry->req,
			  __entry->shadow ? ", shadow": "")
);

/**
 * io_uring_link - called before the io_uring request added into link_list of
 * 				   another request
 *
 * @ctx:			pointer to a ring context structure
 * @req:			pointer to a linked request
 * @target_req:		pointer to a previous request, that would contain @req
 *
 * Allows to track linked requests, to understand dependencies between requests
 * and how does it influence their execution flow.
 */
TRACE_EVENT(io_uring_link,

	TP_PROTO(void *ctx, void *req, void *target_req),

	TP_ARGS(ctx, req, target_req),

	TP_STRUCT__entry (
		__field(  void *,	ctx			)
		__field(  void *,	req			)
		__field(  void *,	target_req	)
	),

	TP_fast_assign(
		__entry->ctx		= ctx;
		__entry->req		= req;
		__entry->target_req	= target_req;
	),

	TP_printk("ring %p, request %p linked after %p",
			  __entry->ctx, __entry->req, __entry->target_req)
);

/**
 * io_uring_cqring_wait - called before start waiting for an available CQE
 *
 * @ctx:		pointer to a ring context structure
 * @min_events:	minimal number of events to wait for
 *
 * Allows to track waiting for CQE, so that we can e.g. troubleshoot
 * situations, when an application wants to wait for an event, that never
 * comes.
 */
TRACE_EVENT(io_uring_cqring_wait,

	TP_PROTO(void *ctx, int min_events),

	TP_ARGS(ctx, min_events),

	TP_STRUCT__entry (
		__field(  void *,	ctx			)
		__field(  int,		min_events	)
	),

	TP_fast_assign(
		__entry->ctx	= ctx;
		__entry->min_events	= min_events;
	),

	TP_printk("ring %p, min_events %d", __entry->ctx, __entry->min_events)
);

/**
 * io_uring_fail_link - called before failing a linked request
 *
 * @req:	request, which links were cancelled
 * @link:	cancelled link
 *
 * Allows to track linked requests cancellation, to see not only that some work
 * was cancelled, but also which request was the reason.
 */
TRACE_EVENT(io_uring_fail_link,

	TP_PROTO(void *req, void *link),

	TP_ARGS(req, link),

	TP_STRUCT__entry (
		__field(  void *,	req		)
		__field(  void *,	link	)
	),

	TP_fast_assign(
		__entry->req	= req;
		__entry->link	= link;
	),

	TP_printk("request %p, link %p", __entry->req, __entry->link)
);

287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
/**
 * io_uring_complete - called when completing an SQE
 *
 * @ctx:		pointer to a ring context structure
 * @user_data:		user data associated with the request
 * @res:		result of the request
 *
 */
TRACE_EVENT(io_uring_complete,

	TP_PROTO(void *ctx, u64 user_data, long res),

	TP_ARGS(ctx, user_data, res),

	TP_STRUCT__entry (
		__field(  void *,	ctx		)
		__field(  u64,		user_data	)
		__field(  long,		res		)
	),

	TP_fast_assign(
		__entry->ctx		= ctx;
		__entry->user_data	= user_data;
		__entry->res		= res;
	),

	TP_printk("ring %p, user_data 0x%llx, result %ld",
			  __entry->ctx, (unsigned long long)__entry->user_data,
			  __entry->res)
);


319 320 321
/**
 * io_uring_submit_sqe - called before submitting one SQE
 *
322 323
 * @ctx:		pointer to a ring context structure
 * @user_data:		user data associated with the request
324 325 326 327 328 329 330 331
 * @force_nonblock:	whether a context blocking or not
 * @sq_thread:		true if sq_thread has submitted this SQE
 *
 * Allows to track SQE submitting, to understand what was the source of it, SQ
 * thread or io_uring_enter call.
 */
TRACE_EVENT(io_uring_submit_sqe,

332
	TP_PROTO(void *ctx, u64 user_data, bool force_nonblock, bool sq_thread),
333

334
	TP_ARGS(ctx, user_data, force_nonblock, sq_thread),
335 336

	TP_STRUCT__entry (
337 338
		__field(  void *,	ctx		)
		__field(  u64,		user_data	)
339
		__field(  bool,		force_nonblock	)
340
		__field(  bool,		sq_thread	)
341 342 343
	),

	TP_fast_assign(
344 345
		__entry->ctx		= ctx;
		__entry->user_data	= user_data;
346
		__entry->force_nonblock	= force_nonblock;
347
		__entry->sq_thread	= sq_thread;
348 349
	),

350 351 352
	TP_printk("ring %p, user data 0x%llx, non block %d, sq_thread %d",
			  __entry->ctx, (unsigned long long) __entry->user_data,
			  __entry->force_nonblock, __entry->sq_thread)
353 354 355 356 357 358
);

#endif /* _TRACE_IO_URING_H */

/* This part must be outside protection */
#include <trace/define_trace.h>