Certain use cases want to use CLOCK_BOOTTIME rather than CLOCK_MONOTONIC, as it doesn't stop updating over suspend. Apart from that, they should behave the same. Add an IORING_TIMEOUT_BOOTTIME flag that allows timeouts and linked timeouts to use CLOCK_BOOTTIME instead. Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> --- diff --git a/fs/io_uring.c b/fs/io_uring.c index 0f827fbe8e6c..39c8631e4d10 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -508,6 +508,7 @@ struct io_timeout_data { struct hrtimer timer; struct timespec64 ts; enum hrtimer_mode mode; + u32 flags; }; struct io_accept { @@ -5725,7 +5726,10 @@ static int io_timeout_update(struct io_ring_ctx *ctx, __u64 user_data, req->timeout.off = 0; /* noseq */ data = req->async_data; list_add_tail(&req->timeout.list, &ctx->timeout_list); - hrtimer_init(&data->timer, CLOCK_MONOTONIC, mode); + if (data->flags & IORING_TIMEOUT_BOOTTIME) + hrtimer_init(&data->timer, CLOCK_BOOTTIME, mode); + else + hrtimer_init(&data->timer, CLOCK_MONOTONIC, mode); data->timer.function = io_timeout_fn; hrtimer_start(&data->timer, timespec64_to_ktime(*ts), mode); return 0; @@ -5807,7 +5811,7 @@ static int io_timeout_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe, if (off && is_timeout_link) return -EINVAL; flags = READ_ONCE(sqe->timeout_flags); - if (flags & ~IORING_TIMEOUT_ABS) + if (flags & ~(IORING_TIMEOUT_ABS | IORING_TIMEOUT_BOOTTIME)) return -EINVAL; req->timeout.off = off; @@ -5819,12 +5823,16 @@ static int io_timeout_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe, data = req->async_data; data->req = req; + data->flags = flags; if (get_timespec64(&data->ts, u64_to_user_ptr(sqe->addr))) return -EFAULT; data->mode = io_translate_timeout_mode(flags); - hrtimer_init(&data->timer, CLOCK_MONOTONIC, data->mode); + if (flags & IORING_TIMEOUT_BOOTTIME) + hrtimer_init(&data->timer, CLOCK_BOOTTIME, data->mode); + else + hrtimer_init(&data->timer, CLOCK_MONOTONIC, data->mode); if (is_timeout_link) { struct io_submit_link *link = &req->ctx->submit_state.link; diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index bb6845e14629..18a4ffd2bbb3 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -151,6 +151,7 @@ enum { */ #define IORING_TIMEOUT_ABS (1U << 0) #define IORING_TIMEOUT_UPDATE (1U << 1) +#define IORING_TIMEOUT_BOOTTIME (1U << 2) /* * sqe->splice_flags -- Jens Axboe