authorgravatar for joran@ronomon.comJoran Dirk Greef <joran@ronomon.com> 2020-09-16 19:36:29+02:00
committergravatar for joran@ronomon.comJoran Dirk Greef <joran@ronomon.com> 2020-09-16 19:36:29+02:00
log491a434b0184bc517cda4f57ef14b4e528e23065
tree83a5b0fcf83cb2c72d1a1ff4e3377589216140fa
parent6f09796ff28f0c73d4ea0b63b02d58215c4450f1

Check kernel support for single_mmap, accept, and read/write


1 files changed, 15 insertions(+), 5 deletions(-)

lib/std/io_uring.zig+15-5
......@@ -95,6 +95,7 @@ pub const IO_Uring = struct {
9595 assert(p.*.resv[0] == 0);
9696 assert(p.*.resv[1] == 0);
9797 assert(p.*.resv[2] == 0);
98 if (!supported) return error.IO_UringKernelNotSupported;
9899
99100 const res = linux.io_uring_setup(entries, p);
100101 try check_errno(res);
......@@ -346,6 +347,7 @@ pub const IO_Uring = struct {
346347 addrlen: *os.socklen_t,
347348 accept_flags: u32
348349 ) !*io_uring_sqe {
350 if (!can_accept) return error.IO_UringKernelCannotAccept;
349351 // "sqe->fd is the file descriptor, sqe->addr holds a pointer to struct sockaddr,
350352 // sqe->addr2 holds a pointer to socklen_t, and finally sqe->accept_flags holds the flags
351353 // for accept(4)." - https://lwn.net/ml/linux-block/20191025173037.13486-1-axboe@kernel.dk/
......@@ -403,6 +405,7 @@ pub const IO_Uring = struct {
403405 buffer: []u8,
404406 offset: u64
405407 ) !*io_uring_sqe {
408 if (!can_read) return error.IO_UringKernelCannotRead;
406409 const sqe = try self.get_sqe();
407410 sqe.* = .{
408411 .opcode = .READ,
......@@ -424,6 +427,7 @@ pub const IO_Uring = struct {
424427 buffer: []const u8,
425428 offset: u64
426429 ) !*io_uring_sqe {
430 if (!can_write) return error.IO_UringKernelCannotWrite;
427431 const sqe = try self.get_sqe();
428432 sqe.* = .{
429433 .opcode = .WRITE,
......@@ -662,8 +666,15 @@ inline fn check_errno(res: usize) !void {
662666 if (errno != 0) return os.unexpectedErrno(errno);
663667}
664668
669const minimum = std.Target.current.os.isAtLeast;
670pub const can_single_mmap = comptime minimum(.linux, .{ .major = 5, .minor = 4 }) == true;
671pub const can_accept = comptime minimum(.linux, .{ .major = 5, .minor = 5 }) == true;
672pub const can_read = comptime minimum(.linux, .{ .major = 5, .minor = 6 }) == true;
673pub const can_write = comptime minimum(.linux, .{ .major = 5, .minor = 6 }) == true;
674pub const supported = can_single_mmap;
675
665676test "queue_nop" {
666 if (builtin.os.tag != .linux) return error.SkipZigTest;
677 if (!supported) return error.SkipZigTest;
667678
668679 var ring = try IO_Uring.init(1, 0);
669680 defer {
......@@ -726,7 +737,7 @@ test "queue_nop" {
726737}
727738
728739test "queue_readv" {
729 if (builtin.os.tag != .linux) return error.SkipZigTest;
740 if (!supported) return error.SkipZigTest;
730741
731742 var ring = try IO_Uring.init(1, 0);
732743 defer ring.deinit();
......@@ -758,7 +769,7 @@ test "queue_readv" {
758769}
759770
760771test "queue_writev/queue_fsync" {
761 if (builtin.os.tag != .linux) return error.SkipZigTest;
772 if (!supported) return error.SkipZigTest;
762773
763774 var ring = try IO_Uring.init(2, 0);
764775 defer ring.deinit();
......@@ -799,8 +810,7 @@ test "queue_writev/queue_fsync" {
799810}
800811
801812test "queue_write/queue_read" {
802 if (builtin.os.tag != .linux) return error.SkipZigTest;
803 // This test may require newer kernel versions.
813 if (!can_read or !can_write) return error.SkipZigTest;
804814
805815 var ring = try IO_Uring.init(2, 0);
806816 defer ring.deinit();