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 {...@@ -95,6 +95,7 @@ pub const IO_Uring = struct {
95 assert(p.*.resv[0] == 0);95 assert(p.*.resv[0] == 0);
96 assert(p.*.resv[1] == 0);96 assert(p.*.resv[1] == 0);
97 assert(p.*.resv[2] == 0);97 assert(p.*.resv[2] == 0);
98 if (!supported) return error.IO_UringKernelNotSupported;
9899
99 const res = linux.io_uring_setup(entries, p);100 const res = linux.io_uring_setup(entries, p);
100 try check_errno(res);101 try check_errno(res);
...@@ -346,6 +347,7 @@ pub const IO_Uring = struct {...@@ -346,6 +347,7 @@ pub const IO_Uring = struct {
346 addrlen: *os.socklen_t,347 addrlen: *os.socklen_t,
347 accept_flags: u32348 accept_flags: u32
348 ) !*io_uring_sqe {349 ) !*io_uring_sqe {
350 if (!can_accept) return error.IO_UringKernelCannotAccept;
349 // "sqe->fd is the file descriptor, sqe->addr holds a pointer to struct sockaddr,351 // "sqe->fd is the file descriptor, sqe->addr holds a pointer to struct sockaddr,
350 // sqe->addr2 holds a pointer to socklen_t, and finally sqe->accept_flags holds the flags352 // sqe->addr2 holds a pointer to socklen_t, and finally sqe->accept_flags holds the flags
351 // for accept(4)." - https://lwn.net/ml/linux-block/20191025173037.13486-1-axboe@kernel.dk/353 // for accept(4)." - https://lwn.net/ml/linux-block/20191025173037.13486-1-axboe@kernel.dk/
...@@ -403,6 +405,7 @@ pub const IO_Uring = struct {...@@ -403,6 +405,7 @@ pub const IO_Uring = struct {
403 buffer: []u8,405 buffer: []u8,
404 offset: u64406 offset: u64
405 ) !*io_uring_sqe {407 ) !*io_uring_sqe {
408 if (!can_read) return error.IO_UringKernelCannotRead;
406 const sqe = try self.get_sqe();409 const sqe = try self.get_sqe();
407 sqe.* = .{410 sqe.* = .{
408 .opcode = .READ,411 .opcode = .READ,
...@@ -424,6 +427,7 @@ pub const IO_Uring = struct {...@@ -424,6 +427,7 @@ pub const IO_Uring = struct {
424 buffer: []const u8,427 buffer: []const u8,
425 offset: u64428 offset: u64
426 ) !*io_uring_sqe {429 ) !*io_uring_sqe {
430 if (!can_write) return error.IO_UringKernelCannotWrite;
427 const sqe = try self.get_sqe();431 const sqe = try self.get_sqe();
428 sqe.* = .{432 sqe.* = .{
429 .opcode = .WRITE,433 .opcode = .WRITE,
...@@ -662,8 +666,15 @@ inline fn check_errno(res: usize) !void {...@@ -662,8 +666,15 @@ inline fn check_errno(res: usize) !void {
662 if (errno != 0) return os.unexpectedErrno(errno);666 if (errno != 0) return os.unexpectedErrno(errno);
663}667}
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
665test "queue_nop" {676test "queue_nop" {
666 if (builtin.os.tag != .linux) return error.SkipZigTest;677 if (!supported) return error.SkipZigTest;
667678
668 var ring = try IO_Uring.init(1, 0);679 var ring = try IO_Uring.init(1, 0);
669 defer {680 defer {
...@@ -726,7 +737,7 @@ test "queue_nop" {...@@ -726,7 +737,7 @@ test "queue_nop" {
726}737}
727738
728test "queue_readv" {739test "queue_readv" {
729 if (builtin.os.tag != .linux) return error.SkipZigTest;740 if (!supported) return error.SkipZigTest;
730741
731 var ring = try IO_Uring.init(1, 0);742 var ring = try IO_Uring.init(1, 0);
732 defer ring.deinit();743 defer ring.deinit();
...@@ -758,7 +769,7 @@ test "queue_readv" {...@@ -758,7 +769,7 @@ test "queue_readv" {
758}769}
759770
760test "queue_writev/queue_fsync" {771test "queue_writev/queue_fsync" {
761 if (builtin.os.tag != .linux) return error.SkipZigTest;772 if (!supported) return error.SkipZigTest;
762773
763 var ring = try IO_Uring.init(2, 0);774 var ring = try IO_Uring.init(2, 0);
764 defer ring.deinit();775 defer ring.deinit();
...@@ -799,8 +810,7 @@ test "queue_writev/queue_fsync" {...@@ -799,8 +810,7 @@ test "queue_writev/queue_fsync" {
799}810}
800811
801test "queue_write/queue_read" {812test "queue_write/queue_read" {
802 if (builtin.os.tag != .linux) return error.SkipZigTest;813 if (!can_read or !can_write) return error.SkipZigTest;
803 // This test may require newer kernel versions.
804814
805 var ring = try IO_Uring.init(2, 0);815 var ring = try IO_Uring.init(2, 0);
806 defer ring.deinit();816 defer ring.deinit();