diff options
Diffstat (limited to 'integrationtests/cmd')
| -rw-r--r-- | integrationtests/cmd/ioworkload/scenarios.go | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/integrationtests/cmd/ioworkload/scenarios.go b/integrationtests/cmd/ioworkload/scenarios.go index c4583e9..06e202d 100644 --- a/integrationtests/cmd/ioworkload/scenarios.go +++ b/integrationtests/cmd/ioworkload/scenarios.go @@ -54,6 +54,9 @@ var scenarios = map[string]func() error{ "sync-sync-file-range": syncSyncFileRange, "truncate-basic": truncateBasic, "truncate-ftruncate": truncateFtruncate, + "iouring-setup": iouringSetup, + "iouring-enter": iouringEnter, + "iouring-register": iouringRegister, } func makeTempDir(prefix string) (string, func(), error) { @@ -1487,3 +1490,89 @@ func openByHandleAtSyscall(mountFD int, handle []byte, flags int) (int, error) { } return int(fd), nil } + +const ( + sysIoUringSetup = 425 + sysIoUringEnter = 426 + sysIoUringRegister = 427 + + // io_uring_params struct size: 10 x uint32 + io_sqring_offsets(40) + io_cqring_offsets(40) = 120 bytes. + ioUringParamsSize = 120 + + ioringRegisterProbe = 8 // IORING_REGISTER_PROBE +) + +// iouringSetup creates an io_uring instance via io_uring_setup(2) and closes the fd. +func iouringSetup() error { + fd, err := ioUringSetupRing(1) + if err != nil { + return err + } + return syscall.Close(fd) +} + +// iouringEnter creates an io_uring instance, then calls io_uring_enter(2) +// with zero submissions/completions to exercise the enter tracepoint. +func iouringEnter() error { + fd, err := ioUringSetupRing(1) + if err != nil { + return err + } + defer syscall.Close(fd) + + _, _, errno := syscall.Syscall6( + sysIoUringEnter, + uintptr(fd), + 0, // to_submit + 0, // min_complete + 0, // flags + 0, // sig + 0, // sz + ) + if errno != 0 { + return fmt.Errorf("io_uring_enter: %w", errno) + } + return nil +} + +// iouringRegister creates an io_uring instance, then calls io_uring_register(2) +// with IORING_REGISTER_PROBE to exercise the register tracepoint. +func iouringRegister() error { + fd, err := ioUringSetupRing(1) + if err != nil { + return err + } + defer syscall.Close(fd) + + // io_uring_probe header is 16 bytes; we don't need probe_op entries. + var probeBuf [16]byte + _, _, errno := syscall.Syscall6( + sysIoUringRegister, + uintptr(fd), + ioringRegisterProbe, + uintptr(unsafe.Pointer(&probeBuf[0])), + 0, // nr_args (0 ops requested) + 0, 0, + ) + runtime.KeepAlive(probeBuf) + if errno != 0 { + return fmt.Errorf("io_uring_register: %w", errno) + } + return nil +} + +// ioUringSetupRing calls io_uring_setup(2) and returns the ring fd. +func ioUringSetupRing(entries uint32) (int, error) { + var params [ioUringParamsSize]byte + fd, _, errno := syscall.Syscall( + sysIoUringSetup, + uintptr(entries), + uintptr(unsafe.Pointer(¶ms[0])), + 0, + ) + runtime.KeepAlive(params) + if errno != 0 { + return 0, fmt.Errorf("io_uring_setup: %w", errno) + } + return int(fd), nil +} |
