To test and profile the overhead of io_uring task_work and the various types of it, add IORING_NOP_TW which tells nop to signal completions through task_work rather than complete them inline.
Unified · Split
| @@ -449,6 +449,7 @@ enum io_uring_msg_ring_flags { · 448 unmodified lines | |||
| 449 | #define IORING_NOP_FILE (1U << 1) | 449 | #define IORING_NOP_FILE (1U << 1) |
| 450 | #define IORING_NOP_FIXED_FILE (1U << 2) | 450 | #define IORING_NOP_FIXED_FILE (1U << 2) |
| 451 | #define IORING_NOP_FIXED_BUFFER (1U << 3) | 451 | #define IORING_NOP_FIXED_BUFFER (1U << 3) |
| 452 | #define IORING_NOP_TW (1U << 4) | ||
| 452 | 453 | ||
| 453 | /* | 454 | /* |
| 454 | * IO completion data structure (Completion Queue Entry) | 455 | * IO completion data structure (Completion Queue Entry) |
| @@ -20,7 +20,8 @@ struct io_nop { · 19 unmodified lines | |||
| 20 | }; | 20 | }; |
| 21 | 21 | ||
| 22 | #define NOP_FLAGS (IORING_NOP_INJECT_RESULT | IORING_NOP_FIXED_FILE | \ | 22 | #define NOP_FLAGS (IORING_NOP_INJECT_RESULT | IORING_NOP_FIXED_FILE | \ |
| 23 | IORING_NOP_FIXED_BUFFER | IORING_NOP_FILE) | 23 | IORING_NOP_FIXED_BUFFER | IORING_NOP_FILE | \ |
| 24 | IORING_NOP_TW) | ||
| 24 | 25 | ||
| 25 | int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) | 26 | int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 26 | { | 27 | { |
| @@ -68,5 +69,10 @@ done: · 41 unmodified lines | |||
| 68 | if (ret < 0) | 69 | if (ret < 0) |
| 69 | req_set_fail(req); | 70 | req_set_fail(req); |
| 70 | io_req_set_res(req, nop->result, 0); | 71 | io_req_set_res(req, nop->result, 0); |
| 72 | if (nop->flags & IORING_NOP_TW) { | ||
| 73 | req->io_task_work.func = io_req_task_complete; | ||
| 74 | io_req_task_work_add(req); | ||
| 75 | return IOU_ISSUE_SKIP_COMPLETE; | ||
| 76 | } | ||
| 71 | return IOU_COMPLETE; | 77 | return IOU_COMPLETE; |
| 72 | } | 78 | } |