Skip to content

Commit cf9446c

Browse files
committed
Merge tag 'io_uring-5.10-2020-10-30' of git://git.kernel.dk/linux-block
Pull io_uring fixes from Jens Axboe: - Fixes for linked timeouts (Pavel) - Set IO_WQ_WORK_CONCURRENT early for async offload (Pavel) - Two minor simplifications that make the code easier to read and follow (Pavel) * tag 'io_uring-5.10-2020-10-30' of git://git.kernel.dk/linux-block: io_uring: use type appropriate io_kiocb handler for double poll io_uring: simplify __io_queue_sqe() io_uring: simplify nxt propagation in io_queue_sqe io_uring: don't miss setting IO_WQ_WORK_CONCURRENT io_uring: don't defer put of cancelled ltimeout io_uring: always clear LINK_TIMEOUT after cancel io_uring: don't adjust LINK_HEAD in cancel ltimeout io_uring: remove opcode check on ltimeout kill
2 parents 8f9a2a1 + c8b5e26 commit cf9446c

1 file changed

Lines changed: 38 additions & 70 deletions

File tree

fs/io_uring.c

Lines changed: 38 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,9 @@ static void io_prep_async_work(struct io_kiocb *req)
13651365
io_req_init_async(req);
13661366
id = req->work.identity;
13671367

1368+
if (req->flags & REQ_F_FORCE_ASYNC)
1369+
req->work.flags |= IO_WQ_WORK_CONCURRENT;
1370+
13681371
if (req->flags & REQ_F_ISREG) {
13691372
if (def->hash_reg_file || (ctx->flags & IORING_SETUP_IOPOLL))
13701373
io_wq_hash_work(&req->work, file_inode(req->file));
@@ -1846,59 +1849,39 @@ static void __io_free_req(struct io_kiocb *req)
18461849
percpu_ref_put(&ctx->refs);
18471850
}
18481851

1849-
static bool io_link_cancel_timeout(struct io_kiocb *req)
1852+
static void io_kill_linked_timeout(struct io_kiocb *req)
18501853
{
1851-
struct io_timeout_data *io = req->async_data;
18521854
struct io_ring_ctx *ctx = req->ctx;
1853-
int ret;
1854-
1855-
ret = hrtimer_try_to_cancel(&io->timer);
1856-
if (ret != -1) {
1857-
io_cqring_fill_event(req, -ECANCELED);
1858-
io_commit_cqring(ctx);
1859-
req->flags &= ~REQ_F_LINK_HEAD;
1860-
io_put_req_deferred(req, 1);
1861-
return true;
1862-
}
1863-
1864-
return false;
1865-
}
1866-
1867-
static bool __io_kill_linked_timeout(struct io_kiocb *req)
1868-
{
18691855
struct io_kiocb *link;
1870-
bool wake_ev;
1856+
bool cancelled = false;
1857+
unsigned long flags;
18711858

1872-
if (list_empty(&req->link_list))
1873-
return false;
1874-
link = list_first_entry(&req->link_list, struct io_kiocb, link_list);
1875-
if (link->opcode != IORING_OP_LINK_TIMEOUT)
1876-
return false;
1859+
spin_lock_irqsave(&ctx->completion_lock, flags);
1860+
link = list_first_entry_or_null(&req->link_list, struct io_kiocb,
1861+
link_list);
18771862
/*
18781863
* Can happen if a linked timeout fired and link had been like
18791864
* req -> link t-out -> link t-out [-> ...]
18801865
*/
1881-
if (!(link->flags & REQ_F_LTIMEOUT_ACTIVE))
1882-
return false;
1866+
if (link && (link->flags & REQ_F_LTIMEOUT_ACTIVE)) {
1867+
struct io_timeout_data *io = link->async_data;
1868+
int ret;
18831869

1884-
list_del_init(&link->link_list);
1885-
wake_ev = io_link_cancel_timeout(link);
1870+
list_del_init(&link->link_list);
1871+
ret = hrtimer_try_to_cancel(&io->timer);
1872+
if (ret != -1) {
1873+
io_cqring_fill_event(link, -ECANCELED);
1874+
io_commit_cqring(ctx);
1875+
cancelled = true;
1876+
}
1877+
}
18861878
req->flags &= ~REQ_F_LINK_TIMEOUT;
1887-
return wake_ev;
1888-
}
1889-
1890-
static void io_kill_linked_timeout(struct io_kiocb *req)
1891-
{
1892-
struct io_ring_ctx *ctx = req->ctx;
1893-
unsigned long flags;
1894-
bool wake_ev;
1895-
1896-
spin_lock_irqsave(&ctx->completion_lock, flags);
1897-
wake_ev = __io_kill_linked_timeout(req);
18981879
spin_unlock_irqrestore(&ctx->completion_lock, flags);
18991880

1900-
if (wake_ev)
1881+
if (cancelled) {
19011882
io_cqring_ev_posted(ctx);
1883+
io_put_req(link);
1884+
}
19021885
}
19031886

19041887
static struct io_kiocb *io_req_link_next(struct io_kiocb *req)
@@ -4977,8 +4960,10 @@ static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode,
49774960
/* make sure double remove sees this as being gone */
49784961
wait->private = NULL;
49794962
spin_unlock(&poll->head->lock);
4980-
if (!done)
4981-
__io_async_wake(req, poll, mask, io_poll_task_func);
4963+
if (!done) {
4964+
/* use wait func handler, so it matches the rq type */
4965+
poll->wait.func(&poll->wait, mode, sync, key);
4966+
}
49824967
}
49834968
refcount_dec(&req->refs);
49844969
return 1;
@@ -6180,7 +6165,6 @@ static struct io_kiocb *io_prep_linked_timeout(struct io_kiocb *req)
61806165
static void __io_queue_sqe(struct io_kiocb *req, struct io_comp_state *cs)
61816166
{
61826167
struct io_kiocb *linked_timeout;
6183-
struct io_kiocb *nxt;
61846168
const struct cred *old_creds = NULL;
61856169
int ret;
61866170

@@ -6206,7 +6190,6 @@ static void __io_queue_sqe(struct io_kiocb *req, struct io_comp_state *cs)
62066190
*/
62076191
if (ret == -EAGAIN && !(req->flags & REQ_F_NOWAIT)) {
62086192
if (!io_arm_poll_handler(req)) {
6209-
punt:
62106193
/*
62116194
* Queued up for async execution, worker will release
62126195
* submit reference when the iocb is actually submitted.
@@ -6216,33 +6199,25 @@ static void __io_queue_sqe(struct io_kiocb *req, struct io_comp_state *cs)
62166199

62176200
if (linked_timeout)
62186201
io_queue_linked_timeout(linked_timeout);
6219-
goto exit;
6220-
}
6202+
} else if (likely(!ret)) {
6203+
/* drop submission reference */
6204+
req = io_put_req_find_next(req);
6205+
if (linked_timeout)
6206+
io_queue_linked_timeout(linked_timeout);
62216207

6222-
if (unlikely(ret)) {
6208+
if (req) {
6209+
if (!(req->flags & REQ_F_FORCE_ASYNC))
6210+
goto again;
6211+
io_queue_async_work(req);
6212+
}
6213+
} else {
62236214
/* un-prep timeout, so it'll be killed as any other linked */
62246215
req->flags &= ~REQ_F_LINK_TIMEOUT;
62256216
req_set_fail_links(req);
62266217
io_put_req(req);
62276218
io_req_complete(req, ret);
6228-
goto exit;
62296219
}
62306220

6231-
/* drop submission reference */
6232-
nxt = io_put_req_find_next(req);
6233-
if (linked_timeout)
6234-
io_queue_linked_timeout(linked_timeout);
6235-
6236-
if (nxt) {
6237-
req = nxt;
6238-
6239-
if (req->flags & REQ_F_FORCE_ASYNC) {
6240-
linked_timeout = NULL;
6241-
goto punt;
6242-
}
6243-
goto again;
6244-
}
6245-
exit:
62466221
if (old_creds)
62476222
revert_creds(old_creds);
62486223
}
@@ -6266,13 +6241,6 @@ static void io_queue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
62666241
if (unlikely(ret))
62676242
goto fail_req;
62686243
}
6269-
6270-
/*
6271-
* Never try inline submit of IOSQE_ASYNC is set, go straight
6272-
* to async execution.
6273-
*/
6274-
io_req_init_async(req);
6275-
req->work.flags |= IO_WQ_WORK_CONCURRENT;
62766244
io_queue_async_work(req);
62776245
} else {
62786246
if (sqe) {

0 commit comments

Comments
 (0)