| ... | @@ -2181,29 +2181,41 @@ test "timeout_remove" { | ... | @@ -2181,29 +2181,41 @@ test "timeout_remove" { |
| 2181 | | 2181 | |
| 2182 | try testing.expectEqual(@as(u32, 2), try ring.submit()); | 2182 | try testing.expectEqual(@as(u32, 2), try ring.submit()); |
| 2183 | | 2183 | |
| 2184 | const cqe_timeout = try ring.copy_cqe(); | 2184 | // The order in which the CQE arrive is not clearly documented and it changed with kernel 5.18: |
| 2185 | // IORING_OP_TIMEOUT_REMOVE is not supported by this kernel version: | 2185 | // * kernel 5.10 gives user data 0x88888888 first, 0x99999999 second |
| 2186 | // Timeout remove operations set the fd to -1, which results in EBADF before EINVAL. | 2186 | // * kernel 5.18 gives user data 0x99999999 first, 0x88888888 second |
| 2187 | // We use IORING_FEAT_RW_CUR_POS as a safety check here to make sure we are at least pre-5.6. | 2187 | |
| 2188 | // We don't want to skip this test for newer kernels. | 2188 | var cqes: [2]os.linux.io_uring_cqe = undefined; |
| 2189 | if (cqe_timeout.user_data == 0x99999999 and | 2189 | try testing.expectEqual(@as(u32, 2), try ring.copy_cqes(cqes[0..], 2)); |
| 2190 | cqe_timeout.err() == .BADF and | 2190 | |
| 2191 | (ring.features & linux.IORING_FEAT_RW_CUR_POS) == 0) | 2191 | for (cqes) |cqe| { |
| 2192 | { | 2192 | // IORING_OP_TIMEOUT_REMOVE is not supported by this kernel version: |
| 2193 | return error.SkipZigTest; | 2193 | // Timeout remove operations set the fd to -1, which results in EBADF before EINVAL. |
| 2194 | } | 2194 | // We use IORING_FEAT_RW_CUR_POS as a safety check here to make sure we are at least pre-5.6. |
| 2195 | try testing.expectEqual(linux.io_uring_cqe{ | 2195 | // We don't want to skip this test for newer kernels. |
| 2196 | .user_data = 0x88888888, | 2196 | if (cqe.user_data == 0x99999999 and |
| 2197 | .res = -@as(i32, @enumToInt(linux.E.CANCELED)), | 2197 | cqe.err() == .BADF and |
| 2198 | .flags = 0, | 2198 | (ring.features & linux.IORING_FEAT_RW_CUR_POS) == 0) |
| 2199 | }, cqe_timeout); | 2199 | { |
| | 2200 | return error.SkipZigTest; |
| | 2201 | } |
| 2200 | | 2202 | |
| 2201 | const cqe_timeout_remove = try ring.copy_cqe(); | 2203 | try testing.expect(cqe.user_data == 0x88888888 or cqe.user_data == 0x99999999); |
| 2202 | try testing.expectEqual(linux.io_uring_cqe{ | 2204 | |
| 2203 | .user_data = 0x99999999, | 2205 | if (cqe.user_data == 0x88888888) { |
| 2204 | .res = 0, | 2206 | try testing.expectEqual(linux.io_uring_cqe{ |
| 2205 | .flags = 0, | 2207 | .user_data = 0x88888888, |
| 2206 | }, cqe_timeout_remove); | 2208 | .res = -@as(i32, @enumToInt(linux.E.CANCELED)), |
| | 2209 | .flags = 0, |
| | 2210 | }, cqe); |
| | 2211 | } else if (cqe.user_data == 0x99999999) { |
| | 2212 | try testing.expectEqual(linux.io_uring_cqe{ |
| | 2213 | .user_data = 0x99999999, |
| | 2214 | .res = 0, |
| | 2215 | .flags = 0, |
| | 2216 | }, cqe); |
| | 2217 | } |
| | 2218 | } |
| 2207 | } | 2219 | } |
| 2208 | | 2220 | |
| 2209 | test "accept/connect/recv/link_timeout" { | 2221 | test "accept/connect/recv/link_timeout" { |
| ... | @@ -2989,7 +3001,7 @@ test "remove_buffers" { | ... | @@ -2989,7 +3001,7 @@ test "remove_buffers" { |
| 2989 | try testing.expectEqual(@as(u64, 0xcccccccc), cqe.user_data); | 3001 | try testing.expectEqual(@as(u64, 0xcccccccc), cqe.user_data); |
| 2990 | } | 3002 | } |
| 2991 | | 3003 | |
| 2992 | // Remove the first 3 buffers | 3004 | // Remove 3 buffers |
| 2993 | | 3005 | |
| 2994 | { | 3006 | { |
| 2995 | var sqe = try ring.remove_buffers(0xbababababa, 3, group_id); | 3007 | var sqe = try ring.remove_buffers(0xbababababa, 3, group_id); |
| ... | @@ -3021,7 +3033,7 @@ test "remove_buffers" { | ... | @@ -3021,7 +3033,7 @@ test "remove_buffers" { |
| 3021 | | 3033 | |
| 3022 | try testing.expect(cqe.flags & linux.IORING_CQE_F_BUFFER == linux.IORING_CQE_F_BUFFER); | 3034 | try testing.expect(cqe.flags & linux.IORING_CQE_F_BUFFER == linux.IORING_CQE_F_BUFFER); |
| 3023 | const used_buffer_id = cqe.flags >> 16; | 3035 | const used_buffer_id = cqe.flags >> 16; |
| 3024 | try testing.expectEqual(used_buffer_id, 0); | 3036 | try testing.expect(used_buffer_id >= 0 and used_buffer_id < 4); |
| 3025 | try testing.expectEqual(@as(i32, buffer_len), cqe.res); | 3037 | try testing.expectEqual(@as(i32, buffer_len), cqe.res); |
| 3026 | try testing.expectEqual(@as(u64, 0xdfdfdfdf), cqe.user_data); | 3038 | try testing.expectEqual(@as(u64, 0xdfdfdfdf), cqe.user_data); |
| 3027 | try testing.expectEqualSlices(u8, &([_]u8{0} ** buffer_len), buffers[used_buffer_id][0..@intCast(usize, cqe.res)]); | 3039 | try testing.expectEqualSlices(u8, &([_]u8{0} ** buffer_len), buffers[used_buffer_id][0..@intCast(usize, cqe.res)]); |