Commit 702bfc89 authored by Linus Torvalds's avatar Linus Torvalds

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
parents f016a540 c8d317aa
...@@ -3049,6 +3049,7 @@ static int io_async_buf_func(struct wait_queue_entry *wait, unsigned mode, ...@@ -3049,6 +3049,7 @@ static int io_async_buf_func(struct wait_queue_entry *wait, unsigned mode,
if (!wake_page_match(wpq, key)) if (!wake_page_match(wpq, key))
return 0; return 0;
req->rw.kiocb.ki_flags &= ~IOCB_WAITQ;
list_del_init(&wait->entry); list_del_init(&wait->entry);
init_task_work(&req->task_work, io_req_task_submit); init_task_work(&req->task_work, io_req_task_submit);
...@@ -3106,6 +3107,7 @@ static bool io_rw_should_retry(struct io_kiocb *req) ...@@ -3106,6 +3107,7 @@ static bool io_rw_should_retry(struct io_kiocb *req)
wait->wait.flags = 0; wait->wait.flags = 0;
INIT_LIST_HEAD(&wait->wait.entry); INIT_LIST_HEAD(&wait->wait.entry);
kiocb->ki_flags |= IOCB_WAITQ; kiocb->ki_flags |= IOCB_WAITQ;
kiocb->ki_flags &= ~IOCB_NOWAIT;
kiocb->ki_waitq = wait; kiocb->ki_waitq = wait;
io_get_req_task(req); io_get_req_task(req);
...@@ -4743,6 +4745,8 @@ static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode, ...@@ -4743,6 +4745,8 @@ static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode,
if (mask && !(mask & poll->events)) if (mask && !(mask & poll->events))
return 0; return 0;
list_del_init(&wait->entry);
if (poll && poll->head) { if (poll && poll->head) {
bool done; bool done;
...@@ -8412,11 +8416,19 @@ static int io_uring_show_cred(int id, void *p, void *data) ...@@ -8412,11 +8416,19 @@ static int io_uring_show_cred(int id, void *p, void *data)
static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m) static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
{ {
bool has_lock;
int i; int i;
mutex_lock(&ctx->uring_lock); /*
* Avoid ABBA deadlock between the seq lock and the io_uring mutex,
* since fdinfo case grabs it in the opposite direction of normal use
* cases. If we fail to get the lock, we just don't iterate any
* structures that could be going away outside the io_uring mutex.
*/
has_lock = mutex_trylock(&ctx->uring_lock);
seq_printf(m, "UserFiles:\t%u\n", ctx->nr_user_files); seq_printf(m, "UserFiles:\t%u\n", ctx->nr_user_files);
for (i = 0; i < ctx->nr_user_files; i++) { for (i = 0; has_lock && i < ctx->nr_user_files; i++) {
struct fixed_file_table *table; struct fixed_file_table *table;
struct file *f; struct file *f;
...@@ -8428,13 +8440,13 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m) ...@@ -8428,13 +8440,13 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
seq_printf(m, "%5u: <none>\n", i); seq_printf(m, "%5u: <none>\n", i);
} }
seq_printf(m, "UserBufs:\t%u\n", ctx->nr_user_bufs); seq_printf(m, "UserBufs:\t%u\n", ctx->nr_user_bufs);
for (i = 0; i < ctx->nr_user_bufs; i++) { for (i = 0; has_lock && i < ctx->nr_user_bufs; i++) {
struct io_mapped_ubuf *buf = &ctx->user_bufs[i]; struct io_mapped_ubuf *buf = &ctx->user_bufs[i];
seq_printf(m, "%5u: 0x%llx/%u\n", i, buf->ubuf, seq_printf(m, "%5u: 0x%llx/%u\n", i, buf->ubuf,
(unsigned int) buf->len); (unsigned int) buf->len);
} }
if (!idr_is_empty(&ctx->personality_idr)) { if (has_lock && !idr_is_empty(&ctx->personality_idr)) {
seq_printf(m, "Personalities:\n"); seq_printf(m, "Personalities:\n");
idr_for_each(&ctx->personality_idr, io_uring_show_cred, m); idr_for_each(&ctx->personality_idr, io_uring_show_cred, m);
} }
...@@ -8449,7 +8461,8 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m) ...@@ -8449,7 +8461,8 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
req->task->task_works != NULL); req->task->task_works != NULL);
} }
spin_unlock_irq(&ctx->completion_lock); spin_unlock_irq(&ctx->completion_lock);
mutex_unlock(&ctx->uring_lock); if (has_lock)
mutex_unlock(&ctx->uring_lock);
} }
static void io_uring_show_fdinfo(struct seq_file *m, struct file *f) static void io_uring_show_fdinfo(struct seq_file *m, struct file *f)
......
...@@ -2365,7 +2365,11 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb, ...@@ -2365,7 +2365,11 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,
} }
if (!PageUptodate(page)) { if (!PageUptodate(page)) {
error = lock_page_killable(page); if (iocb->ki_flags & IOCB_WAITQ)
error = lock_page_async(page, iocb->ki_waitq);
else
error = lock_page_killable(page);
if (unlikely(error)) if (unlikely(error))
goto readpage_error; goto readpage_error;
if (!PageUptodate(page)) { if (!PageUptodate(page)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment