Skip to content

Commit 702bfc8

Browse files
committed
Merge tag 'io_uring-5.9-2020-10-02' of git://git.kernel.dk/linux-block
Pull io_uring fixes from Jens Axboe: - fix for async buffered reads if read-ahead is fully disabled (Hao) - double poll match fix - ->show_fdinfo() potential ABBA deadlock complaint fix * tag 'io_uring-5.9-2020-10-02' of git://git.kernel.dk/linux-block: io_uring: fix async buffered reads when readahead is disabled io_uring: fix potential ABBA deadlock in ->show_fdinfo() io_uring: always delete double poll wait entry on match
2 parents f016a54 + c8d317a commit 702bfc8

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

fs/io_uring.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3049,6 +3049,7 @@ static int io_async_buf_func(struct wait_queue_entry *wait, unsigned mode,
30493049
if (!wake_page_match(wpq, key))
30503050
return 0;
30513051

3052+
req->rw.kiocb.ki_flags &= ~IOCB_WAITQ;
30523053
list_del_init(&wait->entry);
30533054

30543055
init_task_work(&req->task_work, io_req_task_submit);
@@ -3106,6 +3107,7 @@ static bool io_rw_should_retry(struct io_kiocb *req)
31063107
wait->wait.flags = 0;
31073108
INIT_LIST_HEAD(&wait->wait.entry);
31083109
kiocb->ki_flags |= IOCB_WAITQ;
3110+
kiocb->ki_flags &= ~IOCB_NOWAIT;
31093111
kiocb->ki_waitq = wait;
31103112

31113113
io_get_req_task(req);
@@ -4743,6 +4745,8 @@ static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode,
47434745
if (mask && !(mask & poll->events))
47444746
return 0;
47454747

4748+
list_del_init(&wait->entry);
4749+
47464750
if (poll && poll->head) {
47474751
bool done;
47484752

@@ -8412,11 +8416,19 @@ static int io_uring_show_cred(int id, void *p, void *data)
84128416

84138417
static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
84148418
{
8419+
bool has_lock;
84158420
int i;
84168421

8417-
mutex_lock(&ctx->uring_lock);
8422+
/*
8423+
* Avoid ABBA deadlock between the seq lock and the io_uring mutex,
8424+
* since fdinfo case grabs it in the opposite direction of normal use
8425+
* cases. If we fail to get the lock, we just don't iterate any
8426+
* structures that could be going away outside the io_uring mutex.
8427+
*/
8428+
has_lock = mutex_trylock(&ctx->uring_lock);
8429+
84188430
seq_printf(m, "UserFiles:\t%u\n", ctx->nr_user_files);
8419-
for (i = 0; i < ctx->nr_user_files; i++) {
8431+
for (i = 0; has_lock && i < ctx->nr_user_files; i++) {
84208432
struct fixed_file_table *table;
84218433
struct file *f;
84228434

@@ -8428,13 +8440,13 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
84288440
seq_printf(m, "%5u: <none>\n", i);
84298441
}
84308442
seq_printf(m, "UserBufs:\t%u\n", ctx->nr_user_bufs);
8431-
for (i = 0; i < ctx->nr_user_bufs; i++) {
8443+
for (i = 0; has_lock && i < ctx->nr_user_bufs; i++) {
84328444
struct io_mapped_ubuf *buf = &ctx->user_bufs[i];
84338445

84348446
seq_printf(m, "%5u: 0x%llx/%u\n", i, buf->ubuf,
84358447
(unsigned int) buf->len);
84368448
}
8437-
if (!idr_is_empty(&ctx->personality_idr)) {
8449+
if (has_lock && !idr_is_empty(&ctx->personality_idr)) {
84388450
seq_printf(m, "Personalities:\n");
84398451
idr_for_each(&ctx->personality_idr, io_uring_show_cred, m);
84408452
}
@@ -8449,7 +8461,8 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
84498461
req->task->task_works != NULL);
84508462
}
84518463
spin_unlock_irq(&ctx->completion_lock);
8452-
mutex_unlock(&ctx->uring_lock);
8464+
if (has_lock)
8465+
mutex_unlock(&ctx->uring_lock);
84538466
}
84548467

84558468
static void io_uring_show_fdinfo(struct seq_file *m, struct file *f)

mm/filemap.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2365,7 +2365,11 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,
23652365
}
23662366

23672367
if (!PageUptodate(page)) {
2368-
error = lock_page_killable(page);
2368+
if (iocb->ki_flags & IOCB_WAITQ)
2369+
error = lock_page_async(page, iocb->ki_waitq);
2370+
else
2371+
error = lock_page_killable(page);
2372+
23692373
if (unlikely(error))
23702374
goto readpage_error;
23712375
if (!PageUptodate(page)) {

0 commit comments

Comments
 (0)