--- x/include/linux/io_uring_types.h +++ y/include/linux/io_uring_types.h @@ -578,6 +578,7 @@ struct io_kiocb { struct io_kiocb *link; /* custom credentials, valid IFF REQ_F_CREDS is set */ const struct cred *creds; + struct file *poll_file; struct io_wq_work work; }; --- x/io_uring/poll.c +++ y/io_uring/poll.c @@ -714,6 +714,8 @@ int io_arm_poll_handler(struct io_kiocb io_kbuf_recycle(req, issue_flags); + get_file(req->file); + req->poll_file = req->file; ret = __io_arm_poll_handler(req, &apoll->poll, &ipt, mask, issue_flags); if (ret) return ret > 0 ? IO_APOLL_READY : IO_APOLL_ABORTED; @@ -943,6 +945,8 @@ int io_poll_add(struct io_kiocb *req, un if (req->ctx->flags & (IORING_SETUP_SQPOLL|IORING_SETUP_SINGLE_ISSUER)) req->flags |= REQ_F_HASH_LOCKED; + get_file(req->file); + req->poll_file = req->file; ret = __io_arm_poll_handler(req, poll, &ipt, poll->events, issue_flags); if (ret > 0) { io_req_set_res(req, ipt.result_mask, 0); --- x/io_uring/io_uring.c +++ y/io_uring/io_uring.c @@ -975,7 +975,8 @@ static void __io_req_complete_post(struc */ io_put_kbuf_comp(req); io_dismantle_req(req); - io_put_task(req->task, 1); + if (req->poll_file) + fput(req->poll_file); wq_list_add_head(&req->comp_list, &ctx->locked_free_list); ctx->locked_free_nr++; } @@ -1099,6 +1100,8 @@ __cold void io_free_req(struct io_kiocb io_req_put_rsrc(req); io_dismantle_req(req); io_put_task(req->task, 1); + if (req->poll_file) + fput(req->poll_file); spin_lock(&ctx->completion_lock); wq_list_add_head(&req->comp_list, &ctx->locked_free_list); @@ -1296,6 +1299,8 @@ void __io_req_task_work_add(struct io_ki if (!llist_add(&req->io_task_work.node, &tctx->task_list)) return; + if (req->flags & REQ_F_REFCOUNT) + req_ref_get(req); if (ctx->flags & IORING_SETUP_TASKRUN_FLAG) atomic_or(IORING_SQ_TASKRUN, &ctx->rings->sq_flags); @@ -1458,7 +1463,7 @@ void io_free_batch_list(struct io_ring_c } task_refs++; node = req->comp_list.next; - io_req_add_to_cache(req, ctx); + kmem_cache_free(req_cachep, req); } while (node); if (task) @@ -2140,6 +2145,7 @@ static int io_init_req(struct io_ring_ct req->flags = sqe_flags = READ_ONCE(sqe->flags); req->cqe.user_data = READ_ONCE(sqe->user_data); req->file = NULL; + req->poll_file = NULL; req->rsrc_node = NULL; req->task = current; @@ -2728,6 +2734,7 @@ static void io_req_caches_free(struct io { int nr = 0; + flush_delayed_work(&ctx->fallback_work); mutex_lock(&ctx->uring_lock); io_flush_cached_locked_reqs(ctx, &ctx->submit_state);