Skip to content

Commit 9c8e11b

Browse files
isilenceaxboe
authored andcommitted
io_uring: add timeout update
Support timeout updates through IORING_OP_TIMEOUT_REMOVE with passed in IORING_TIMEOUT_UPDATE. Updates doesn't support offset timeout mode. Oirignal timeout.off will be ignored as well. Signed-off-by: Pavel Begunkov <[email protected]> [axboe: remove now unused 'ret' variable] Signed-off-by: Jens Axboe <[email protected]>
1 parent fbd1584 commit 9c8e11b

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

fs/io_uring.c

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,10 @@ struct io_timeout {
453453
struct io_timeout_rem {
454454
struct file *file;
455455
u64 addr;
456+
457+
/* timeout update */
458+
struct timespec64 ts;
459+
u32 flags;
456460
};
457461

458462
struct io_rw {
@@ -867,7 +871,10 @@ static const struct io_op_def io_op_defs[] = {
867871
.async_size = sizeof(struct io_timeout_data),
868872
.work_flags = IO_WQ_WORK_MM,
869873
},
870-
[IORING_OP_TIMEOUT_REMOVE] = {},
874+
[IORING_OP_TIMEOUT_REMOVE] = {
875+
/* used by timeout updates' prep() */
876+
.work_flags = IO_WQ_WORK_MM,
877+
},
871878
[IORING_OP_ACCEPT] = {
872879
.needs_file = 1,
873880
.unbound_nonreg_file = 1,
@@ -5671,17 +5678,48 @@ static int io_timeout_cancel(struct io_ring_ctx *ctx, __u64 user_data)
56715678
return 0;
56725679
}
56735680

5681+
static int io_timeout_update(struct io_ring_ctx *ctx, __u64 user_data,
5682+
struct timespec64 *ts, enum hrtimer_mode mode)
5683+
{
5684+
struct io_kiocb *req = io_timeout_extract(ctx, user_data);
5685+
struct io_timeout_data *data;
5686+
5687+
if (IS_ERR(req))
5688+
return PTR_ERR(req);
5689+
5690+
req->timeout.off = 0; /* noseq */
5691+
data = req->async_data;
5692+
list_add_tail(&req->timeout.list, &ctx->timeout_list);
5693+
hrtimer_init(&data->timer, CLOCK_MONOTONIC, mode);
5694+
data->timer.function = io_timeout_fn;
5695+
hrtimer_start(&data->timer, timespec64_to_ktime(*ts), mode);
5696+
return 0;
5697+
}
5698+
56745699
static int io_timeout_remove_prep(struct io_kiocb *req,
56755700
const struct io_uring_sqe *sqe)
56765701
{
5702+
struct io_timeout_rem *tr = &req->timeout_rem;
5703+
56775704
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
56785705
return -EINVAL;
56795706
if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT)))
56805707
return -EINVAL;
5681-
if (sqe->ioprio || sqe->buf_index || sqe->len || sqe->timeout_flags)
5708+
if (sqe->ioprio || sqe->buf_index || sqe->len)
5709+
return -EINVAL;
5710+
5711+
tr->addr = READ_ONCE(sqe->addr);
5712+
tr->flags = READ_ONCE(sqe->timeout_flags);
5713+
if (tr->flags & IORING_TIMEOUT_UPDATE) {
5714+
if (tr->flags & ~(IORING_TIMEOUT_UPDATE|IORING_TIMEOUT_ABS))
5715+
return -EINVAL;
5716+
if (get_timespec64(&tr->ts, u64_to_user_ptr(sqe->addr2)))
5717+
return -EFAULT;
5718+
} else if (tr->flags) {
5719+
/* timeout removal doesn't support flags */
56825720
return -EINVAL;
5721+
}
56835722

5684-
req->timeout_rem.addr = READ_ONCE(sqe->addr);
56855723
return 0;
56865724
}
56875725

@@ -5690,11 +5728,19 @@ static int io_timeout_remove_prep(struct io_kiocb *req,
56905728
*/
56915729
static int io_timeout_remove(struct io_kiocb *req)
56925730
{
5731+
struct io_timeout_rem *tr = &req->timeout_rem;
56935732
struct io_ring_ctx *ctx = req->ctx;
56945733
int ret;
56955734

56965735
spin_lock_irq(&ctx->completion_lock);
5697-
ret = io_timeout_cancel(ctx, req->timeout_rem.addr);
5736+
if (req->timeout_rem.flags & IORING_TIMEOUT_UPDATE) {
5737+
enum hrtimer_mode mode = (tr->flags & IORING_TIMEOUT_ABS)
5738+
? HRTIMER_MODE_ABS : HRTIMER_MODE_REL;
5739+
5740+
ret = io_timeout_update(ctx, tr->addr, &tr->ts, mode);
5741+
} else {
5742+
ret = io_timeout_cancel(ctx, tr->addr);
5743+
}
56985744

56995745
io_cqring_fill_event(req, ret);
57005746
io_commit_cqring(ctx);

include/uapi/linux/io_uring.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ enum {
151151
* sqe->timeout_flags
152152
*/
153153
#define IORING_TIMEOUT_ABS (1U << 0)
154+
#define IORING_TIMEOUT_UPDATE (1U << 1)
154155

155156
/*
156157
* sqe->splice_flags

0 commit comments

Comments
 (0)