Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 262 additions & 0 deletions core/sys/linux/bits.odin
Original file line number Diff line number Diff line change
Expand Up @@ -1964,3 +1964,265 @@ RISCV_HWProbe_Misaligned_Scalar_Perf :: enum {
UNSUPPORTED,
}

IO_Uring_Enter_Flags_Bits :: enum {
GETEVENTS,
SQ_WAKEUP,
SQ_WAIT,
EXT_ARG, // Available since Linux 5.11
REGISTERED_RING,
}

IO_Uring_Register_Opcode :: enum uint {
REGISTER_BUFFERS = 0,
UNREGISTER_BUFFERS = 1,
REGISTER_FILES = 2,
UNREGISTER_FILES = 3,
REGISTER_EVENTFD = 4,
UNREGISTER_EVENTFD = 5,
REGISTER_FILES_UPDATE = 6,
REGISTER_EVENTFD_ASYNC = 7,
REGISTER_PROBE = 8,
REGISTER_PERSONALITY = 9,
UNREGISTER_PERSONALITY = 10,
REGISTER_RESTRICTIONS = 11,
REGISTER_ENABLE_RINGS = 12,
/* extended with tagging */
REGISTER_FILES2 = 13,
REGISTER_FILES_UPDATE2 = 14,
REGISTER_BUFFERS2 = 15,
REGISTER_BUFFERS_UPDATE = 16,
/* set/clear io-wq thread affinities */
REGISTER_IOWQ_AFF = 17,
UNREGISTER_IOWQ_AFF = 18,
/* set/get max number of io-wq workers */
REGISTER_IOWQ_MAX_WORKERS = 19,
/* register/unregister io_uring fd with the ring */
REGISTER_RING_FDS = 20,
UNREGISTER_RING_FDS = 21,
/* register ring based provide buffer group */
REGISTER_PBUF_RING = 22,
UNREGISTER_PBUF_RING = 23,
/* sync cancelation API */
REGISTER_SYNC_CANCEL = 24,
/* register a range of fixed file slots for automatic slot allocation */
REGISTER_FILE_ALLOC_RANGE = 25,
/* this goes last */
REGISTER_LAST,
/* flag added to the opcode to use a registered ring fd */
REGISTER_USE_REGISTERED_RING = 1 << 31,
}

IO_Uring_Setup_Flags_Bits :: enum {
// io_context is polled.
IOPOLL,
// SQ poll thread.
SQPOLL,
// sq_thread_cpu is valid.
SQ_AFF,
// app defines CQ size.
CQSIZE,
// clamp SQ/CQ ring sizes.
CLAMP,
// attach to existing wq.
ATTACH_WQ,
// start with ring disabled.
R_DISABLED,
// continue submit on error.
SUBMIT_ALL,
// Cooperative task running. When requests complete, they often require
// forcing the submitter to transition to the kernel to complete. If this
// flag is set, work will be done when the task transitions anyway, rather
// than force an inter-processor interrupt reschedule. This avoids interrupting
// a task running in userspace, and saves an IPI.
COOP_TASKRUN,
// If COOP_TASKRUN is set, get notified if task work is available for
// running and a kernel transition would be needed to run it. This sets
// IORING_SQ_TASKRUN in the sq ring flags. Not valid with COOP_TASKRUN.
TASKRUN_FLAG,
// SQEs are 128 bytes.
SQE128,
// CQEs are 32 bytes.
CQE32,
// Only one task is allowed to submit requests
SINGLE_ISSUER,
// Defer running task work to get events.
// Rather than running bits of task work whenever the task transitions
// try to do it just before it is needed.
DEFER_TASKRUN,
}

IO_Uring_Features_Bits :: enum {
SINGLE_MMAP,
NODROP,
SUBMIT_STABLE,
RW_CUR_POS,
CUR_PERSONALITY,
FAST_POLL,
POLL_32BITS,
SQPOLL_NONFIXED,
EXT_ARG,
NATIVE_WORKERS,
RSRC_TAGS,
}

IO_Uring_CQE_Flags_Bits :: enum {
// If set, the upper 16 bits are the buffer ID.
BUFFER,
// If set, parent SQE will generate more CQE entries.
MORE,
// If set, more data to read after socket recv.
SOCK_NONEMPTY,
// Set for notification CQEs. Can be used to distinct them from sends.
NOTIF,
}

IO_Uring_OP :: enum u8 {
NOP,
READV,
WRITEV,
FSYNC,
READ_FIXED,
WRITE_FIXED,
POLL_ADD,
POLL_REMOVE,
SYNC_FILE_RANGE,
SENDMSG,
RECVMSG,
TIMEOUT,
TIMEOUT_REMOVE,
ACCEPT,
ASYNC_CANCEL,
LINK_TIMEOUT,
CONNECT,
FALLOCATE,
OPENAT,
CLOSE,
FILES_UPDATE,
STATX,
READ,
WRITE,
FADVISE,
MADVISE,
SEND,
RECV,
OPENAT2,
EPOLL_CTL,
SPLICE,
PROVIDE_BUFFERS,
REMOVE_BUFFERS,
TEE,
SHUTDOWN,
RENAMEAT,
UNLINKAT,
MKDIRAT,
SYMLINKAT,
LINKAT,
MSG_RING,
FSETXATTR,
SETXATTR,
FGETXATTR,
GETXATTR,
SOCKET,
URING_CMD,
SEND_ZC,
SENDMSG_ZC,
READ_MULTISHOT,
WAITID,
FUTEX_WAIT,
FUTEX_WAKE,
FUTEX_WAITV,
FIXED_FD_INSTALL,
FTRUNCATE,
BIND,
LISTEN,
}

IO_Uring_SQE_Flags_Bits :: enum {
// Use fixed fileset.
FIXED_FILE,
// Issue after inflight IO.
IO_DRAIN,
// Links next sqe.
IO_LINK,
// Like LINK, but stronger.
IO_HARDLINK,
// Always go async.
ASYNC,
// Select buffer from sq.buf_group.
BUFFER_SELECT,
// Don't post CQE if request succeeded.
CQE_SKIP_SUCCESS,
}

IO_Uring_Poll_Add_Flags_Bits :: enum {
ADD_MULTI,
UPDATE_EVENTS,
UPDATE_USER_DATA,
ADD_LEVEL,
}

IO_Uring_Fsync_Flags_Bits :: enum {
DATASYNC,
}

IO_Uring_Timeout_Flags_Bits :: enum {
ABS,
UPDATE,
BOOTTIME,
REALTIME,
LINK_TIMEOUT_UPDATE,
ETIME_SUCCESS,
}

IO_Uring_Cmd_Flags_Bits :: enum {
// use registered buffer; pass this flag along with setting sqe.buf_index.
FIXED,
}

IO_Uring_Splice_Flags_Bits :: enum {
MOVE,
NONBLOCK,
MORE,
GIFT,
F_FD_IN_FIXED = 31,
}

IO_Uring_Accept_Flags_Bits :: enum {
MULTISHOT,
}

IO_Uring_Send_Recv_Flags_Bits :: enum {
/*
If set, instead of first attempting to send
or receive and arm poll if that yields an
-EAGAIN result, arm poll upfront and skip
the initial transfer attempt.
*/
RECVSEND_POLL_FIRST,
/*
Multishot recv. Sets IORING_CQE_F_MORE if
the handler will continue to report
CQEs on behalf of the same SQE.
*/
RECV_MULTISHOT,
/*
Use registered buffers, the index is stored in
the buf_index field.
*/
RECVSEND_FIXED_BUF,
/*
If set, SEND[MSG]_ZC should report
the zerocopy usage in cqe.res
for the IORING_CQE_F_NOTIF cqe.
0 is reported if zerocopy was actually possible.
IORING_NOTIF_USAGE_ZC_COPIED if data was copied
(at least partially).
*/
SEND_ZC_REPORT_USAGE,
}

IO_Uring_Submission_Queue_Flags_Bits :: enum {
NEED_WAKEUP,
CQ_OVERFLOW,
TASKRUN,
}
10 changes: 10 additions & 0 deletions core/sys/linux/constants.odin
Original file line number Diff line number Diff line change
Expand Up @@ -395,3 +395,13 @@ MAP_HUGE_16GB :: transmute(Map_Flags)(u32(34) << MAP_HUGE_SHIFT)

/* Get window size */
TIOCGWINSZ :: 0x5413

IORING_TIMEOUT_CLOCK_MASK :: IO_Uring_Timeout_Flags{.BOOTTIME, .REALTIME}
IORING_TIMEOUT_UPDATE_MASK :: IO_Uring_Timeout_Flags{.UPDATE, .LINK_TIMEOUT_UPDATE}

IORING_OFF_SQ_RING :: 0
IORING_OFF_CQ_RING :: 0x8000000
IORING_OFF_SQES :: 0x10000000
IORING_OFF_PBUF_RING :: 0x80000000
IORING_OFF_PBUF_SHIFT :: 16
IORING_OFF_MMAP_MASK :: 0xf8000000
45 changes: 40 additions & 5 deletions core/sys/linux/sys.odin
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ sendfile :: proc "contextless" (out_fd: Fd, in_fd: Fd, offset: ^i64, count: uint
Available since Linux 2.0.
*/
socket :: proc "contextless" (domain: Address_Family, socktype: Socket_Type, sockflags: Socket_FD_Flags, protocol: Protocol) -> (Fd, Errno) {
sock_type_flags: int = cast(int) socktype | transmute(int) sockflags
sock_type_flags: int = cast(int) socktype | cast(int) transmute(i32) sockflags
ret := syscall(SYS_socket, domain, sock_type_flags, protocol)
return errno_unwrap(ret, Fd)
}
Expand Down Expand Up @@ -543,7 +543,7 @@ where
T == Sock_Addr_Any
{
addr_len: i32 = size_of(T)
ret := syscall(SYS_accept4, sock, addr, &addr_len, transmute(int) sockflags)
ret := syscall(SYS_accept4, sock, addr, &addr_len, transmute(i32) sockflags)
return errno_unwrap(ret, Fd)
}

Expand Down Expand Up @@ -2927,11 +2927,46 @@ statx :: proc "contextless" (dir: Fd, pathname: cstring, flags: FD_Flags, mask:

// TODO(flysand): pidfd_send_signal

// TODO(flysand): io_uring_setup
/*
Setup a context for performing asynchronous I/O.

Available since Linux 5.1
*/
io_uring_setup :: proc "contextless" (entries: u32, params: ^IO_Uring_Params) -> (Fd, Errno) {
ret := syscall(SYS_io_uring_setup, entries, params)
return errno_unwrap(ret, Fd)
}

// TODO(flysand): io_uring_enter
/*
Initiate and/or complete I/O using the shared submission and completion queues.

// TODO(flysand): io_uring_register
Available since Linux 5.1
*/
io_uring_enter :: proc "contextless" (fd: Fd, to_submit: u32, min_complete: u32, flags: IO_Uring_Enter_Flags, sig: ^Sig_Set) -> (int, Errno) {
ret := syscall(SYS_io_uring_enter, fd, to_submit, min_complete, transmute(u32)flags, sig, size_of(Sig_Set) if sig != nil else 0)
return errno_unwrap(ret, int)
}

/*
Initiate and.or complete I/O using the shared submission and completion queues.

Available since Linux 5.11
*/
io_uring_enter2 :: proc "contextless" (fd: Fd, to_submit: u32, min_complete: u32, flags: IO_Uring_Enter_Flags, arg: ^IO_Uring_Getevents_Arg) -> (int, Errno) {
assert_contextless(.EXT_ARG in flags)
ret := syscall(SYS_io_uring_enter, fd, to_submit, min_complete, transmute(u32)flags, arg, size_of(IO_Uring_Getevents_Arg))
return errno_unwrap(ret, int)
}

/*
Register files or user buffers for asynchronous I/O.

Available since Linux 5.1
*/
io_uring_register :: proc "contextless" (fd: Fd, opcode: IO_Uring_Register_Opcode, arg: rawptr, nr_args: u32) -> Errno {
ret := syscall(SYS_io_uring_register, fd, opcode, arg, nr_args)
return Errno(-ret)
}

// TODO(flysand): open_tree

Expand Down
Loading