You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> **Note:** The `io_uring:io_uring_submit_sqe` and `io_uring:io_uring_complete` tracepoints are disabled by default due to incompatible struct field layouts across kernel versions. The kprobe-based implementations above provide cross-kernel compatibility.
12
13
14
+
### SQE field capture and file correlation
15
+
16
+
The SUBMIT kprobe on `io_queue_sqe` only receives the internal `struct io_kiocb`, whose layout is **not** ABI-stable across kernel releases, so reading `opcode`/`fd`/`len`/`offset`/`user_data` from it directly is unreliable. Instead these fields are captured at request-**prep** time:
17
+
18
+
-`trace_io_uring_prep_rw` attaches to the read/write prep handler (`io_prep_rw`), which is dispatched through the opcode table (`def->prep`) and therefore is not inlined. It receives the **UAPI `struct io_uring_sqe`** (PARM2), whose leading field offsets are stable for all io_uring kernels. A minimal mirror (`io_uring_sqe_min`) reads `opcode`, `flags`, `ioprio`, `fd`, `off`, `len`, `user_data` and `buf_index`.
19
+
- The same probe reads `req->file` (the first member of `struct io_kiocb` on modern kernels) and, when it is a regular file on a real filesystem, records the backing **inode**, **device** and **superblock magic** via the same helpers used by the VFS probes.
20
+
- These values are staged in the `io_uring_submit_map` (keyed by the `io_kiocb` pointer) and consumed by the SUBMIT, COMPLETE and WORKER probes.
21
+
22
+
If the prep symbol is unavailable on a given kernel, the SUBMIT probe falls back to reading `req->file` directly for inode/device/fs, and the SQE-only fields (`opcode`, `len`, `offset`, `user_data`) simply remain empty — graceful degradation rather than failure.
23
+
24
+
> **Note:** This captures SQE fields for the read/write opcode families (the bulk of filesystem I/O). Other opcodes (e.g. `OPENAT`, `STATX`) are not prepped through `io_prep_rw`, so their `opcode`/`fd`/`len`/`offset` columns may be empty.
| 42 | FS Type |`string`| Source filesystem name from the superblock magic (e.g. `EXT2/3/4`, `XFS`, `BTRFS`); empty otherwise |
72
+
73
+
> Columns 39–42 are appended to the original 38-column schema, so parsers that read only the first 38 fields are unaffected.
55
74
56
75
## Event Types
57
76
@@ -141,6 +160,16 @@ SUBMIT and COMPLETE events share the same `Req Ptr`, enabling latency calculatio
141
160
latency_ns = complete_ts_ns - submit_ts_ns
142
161
```
143
162
163
+
## Mirroring into the fs/VFS trace
164
+
165
+
io_uring read/write operations call `->read_iter`/`->write_iter` directly and **never pass through `vfs_read`/`vfs_write`**, so they are invisible to the VFS probes. To make async I/O visible alongside syscall I/O, each completed io_uring read/write is also emitted into the main **fs/VFS trace** (`fs/fs_*.csv`) using the standard VFS 22-column schema:
-**Trigger:** COMPLETE events only (so `bytes_completed`/`duration_ns` are known), and only when a backing inode was resolved.
169
+
-**Columns:** filename/inode/device/fs_type come from the prep-time file capture; `size` is the SQE length, `bytes_completed`/`errno` from the CQE result, `duration_ns` from the submit→complete latency. The generic `flags` column carries the decoded **SQE flags** (`FIXED_FILE|ASYNC|IO_LINK…`) in place of the open-file `O_*` flags, which are not available on the io_uring path.
170
+
171
+
`fsync` is intentionally **not** mirrored: io_uring `FSYNC` calls `vfs_fsync` internally and is therefore already captured by the VFS fsync probe — mirroring it would double-count. The full async-specific detail (req_ptr, user_data, worker, queue depths) always remains in the dedicated io_uring CSV.
Copy file name to clipboardExpand all lines: docs/traces/VFS_EVENTS.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,6 +22,8 @@
22
22
-`vfs_fallocate` — File space pre-allocation operations
23
23
-`do_sendfile` / `__do_sendfile` — Efficient file-to-file transfer operations
24
24
25
+
> **io_uring-origin rows:**`READ`/`WRITE` operations issued via io_uring bypass `vfs_read`/`vfs_write` (they call `->read_iter`/`->write_iter` directly), so they are mirrored into this trace from the io_uring instrumentation rather than captured by a VFS probe. They use the same schema; their `flags` column carries io_uring SQE flags (`FIXED_FILE|ASYNC|…`) instead of `O_*` flags, and `ppid`/`container_id` are empty. See [IO_URING_EVENTS.md](IO_URING_EVENTS.md#mirroring-into-the-fsvfs-trace). Each such row also has a full-detail counterpart in the io_uring CSV.
26
+
25
27
## Filename Resolution
26
28
27
29
The `filename` field contains the best available path for the file at event time. Full absolute paths are resolved entirely inside the kernel at probe time before the process can exit, so even output from short-lived processes (e.g. `cat`, `ls`) contains correct paths.
0 commit comments