Pull io_uring fixes from Jens Axboe: "The fix for the msghdr->msg_inq assigned value being wrong, using -1 instead of -1U for the signed type. Also a fix for ensuring when we're trying to run task_work on an exiting task, that we wait for it. This is not really a correctness thing as the work is being canceled, but it does help with ensuring file descriptors are closed when the task has exited." * tag 'io_uring-6.5-2023-07-03' of git://git.kernel.dk/linux: io_uring: flush offloaded and delayed task_work on exit io_uring: remove io_fallback_tw() forward declaration io_uring/net: use proper value for msg_inq
Unified · Split
| @@ -149,7 +149,6 @@ static bool io_uring_try_cancel_requests(struct io_ring_ctx *ctx, · 148 unmodified lines | |||
| 149 | static void io_queue_sqe(struct io_kiocb *req); | 149 | static void io_queue_sqe(struct io_kiocb *req); |
| 150 | static void io_move_task_work_from_local(struct io_ring_ctx *ctx); | 150 | static void io_move_task_work_from_local(struct io_ring_ctx *ctx); |
| 151 | static void __io_submit_flush_completions(struct io_ring_ctx *ctx); | 151 | static void __io_submit_flush_completions(struct io_ring_ctx *ctx); |
| 152 | static __cold void io_fallback_tw(struct io_uring_task *tctx); | ||
| 153 | 152 | ||
| 154 | struct kmem_cache *req_cachep; | 153 | struct kmem_cache *req_cachep; |
| 155 | 154 | ||
| @@ -1238,6 +1237,34 @@ static inline struct llist_node *io_llist_cmpxchg(struct llist_head *head, · 1082 unmodified lines | |||
| 1238 | return cmpxchg(&head->first, old, new); | 1237 | return cmpxchg(&head->first, old, new); |
| 1239 | } | 1238 | } |
| 1240 | 1239 | ||
| 1240 | static __cold void io_fallback_tw(struct io_uring_task *tctx, bool sync) | ||
| 1241 | { | ||
| 1242 | struct llist_node *node = llist_del_all(&tctx->task_list); | ||
| 1243 | struct io_ring_ctx *last_ctx = NULL; | ||
| 1244 | struct io_kiocb *req; | ||
| 1245 | |||
| 1246 | while (node) { | ||
| 1247 | req = container_of(node, struct io_kiocb, io_task_work.node); | ||
| 1248 | node = node->next; | ||
| 1249 | if (sync && last_ctx != req->ctx) { | ||
| 1250 | if (last_ctx) { | ||
| 1251 | flush_delayed_work(&last_ctx->fallback_work); | ||
| 1252 | percpu_ref_put(&last_ctx->refs); | ||
| 1253 | } | ||
| 1254 | last_ctx = req->ctx; | ||
| 1255 | percpu_ref_get(&last_ctx->refs); | ||
| 1256 | } | ||
| 1257 | if (llist_add(&req->io_task_work.node, | ||
| 1258 | &req->ctx->fallback_llist)) | ||
| 1259 | schedule_delayed_work(&req->ctx->fallback_work, 1); | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | if (last_ctx) { | ||
| 1263 | flush_delayed_work(&last_ctx->fallback_work); | ||
| 1264 | percpu_ref_put(&last_ctx->refs); | ||
| 1265 | } | ||
| 1266 | } | ||
| 1267 | |||
| 1241 | void tctx_task_work(struct callback_head *cb) | 1268 | void tctx_task_work(struct callback_head *cb) |
| 1242 | { | 1269 | { |
| 1243 | struct io_tw_state ts = {}; | 1270 | struct io_tw_state ts = {}; |
| @@ -1250,7 +1277,7 @@ void tctx_task_work(struct callback_head *cb) · 6 unmodified lines | |||
| 1250 | unsigned int count = 0; | 1277 | unsigned int count = 0; |
| 1251 | 1278 | ||
| 1252 | if (unlikely(current->flags & PF_EXITING)) { | 1279 | if (unlikely(current->flags & PF_EXITING)) { |
| 1253 | io_fallback_tw(tctx); | 1280 | io_fallback_tw(tctx, true); |
| 1254 | return; | 1281 | return; |
| 1255 | } | 1282 | } |
| 1256 | 1283 | ||
| @@ -1279,20 +1306,6 @@ void tctx_task_work(struct callback_head *cb) · 22 unmodified lines | |||
| 1279 | trace_io_uring_task_work_run(tctx, count, loops); | 1306 | trace_io_uring_task_work_run(tctx, count, loops); |
| 1280 | } | 1307 | } |
| 1281 | 1308 | ||
| 1282 | static __cold void io_fallback_tw(struct io_uring_task *tctx) | ||
| 1283 | { | ||
| 1284 | struct llist_node *node = llist_del_all(&tctx->task_list); | ||
| 1285 | struct io_kiocb *req; | ||
| 1286 | |||
| 1287 | while (node) { | ||
| 1288 | req = container_of(node, struct io_kiocb, io_task_work.node); | ||
| 1289 | node = node->next; | ||
| 1290 | if (llist_add(&req->io_task_work.node, | ||
| 1291 | &req->ctx->fallback_llist)) | ||
| 1292 | schedule_delayed_work(&req->ctx->fallback_work, 1); | ||
| 1293 | } | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | static inline void io_req_local_work_add(struct io_kiocb *req, unsigned flags) | 1309 | static inline void io_req_local_work_add(struct io_kiocb *req, unsigned flags) |
| 1297 | { | 1310 | { |
| 1298 | struct io_ring_ctx *ctx = req->ctx; | 1311 | struct io_ring_ctx *ctx = req->ctx; |
| @@ -1359,7 +1372,7 @@ static void io_req_normal_work_add(struct io_kiocb *req) · 60 unmodified lines | |||
| 1359 | if (likely(!task_work_add(req->task, &tctx->task_work, ctx->notify_method))) | 1372 | if (likely(!task_work_add(req->task, &tctx->task_work, ctx->notify_method))) |
| 1360 | return; | 1373 | return; |
| 1361 | 1374 | ||
| 1362 | io_fallback_tw(tctx); | 1375 | io_fallback_tw(tctx, false); |
| 1363 | } | 1376 | } |
| 1364 | 1377 | ||
| 1365 | void __io_req_task_work_add(struct io_kiocb *req, unsigned flags) | 1378 | void __io_req_task_work_add(struct io_kiocb *req, unsigned flags) |
| @@ -3109,6 +3122,8 @@ static __cold void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx) · 1743 unmodified lines | |||
| 3109 | if (ctx->rings) | 3122 | if (ctx->rings) |
| 3110 | io_kill_timeouts(ctx, NULL, true); | 3123 | io_kill_timeouts(ctx, NULL, true); |
| 3111 | 3124 | ||
| 3125 | flush_delayed_work(&ctx->fallback_work); | ||
| 3126 | |||
| 3112 | INIT_WORK(&ctx->exit_work, io_ring_exit_work); | 3127 | INIT_WORK(&ctx->exit_work, io_ring_exit_work); |
| 3113 | /* | 3128 | /* |
| 3114 | * Use system_unbound_wq to avoid spawning tons of event kworkers | 3129 | * Use system_unbound_wq to avoid spawning tons of event kworkers |
| @@ -631,7 +631,7 @@ static inline bool io_recv_finish(struct io_kiocb *req, int *ret, · 630 unmodified lines | |||
| 631 | unsigned int cflags; | 631 | unsigned int cflags; |
| 632 | 632 | ||
| 633 | cflags = io_put_kbuf(req, issue_flags); | 633 | cflags = io_put_kbuf(req, issue_flags); |
| 634 | if (msg->msg_inq && msg->msg_inq != -1U) | 634 | if (msg->msg_inq && msg->msg_inq != -1) |
| 635 | cflags |= IORING_CQE_F_SOCK_NONEMPTY; | 635 | cflags |= IORING_CQE_F_SOCK_NONEMPTY; |
| 636 | 636 | ||
| 637 | if (!(req->flags & REQ_F_APOLL_MULTISHOT)) { | 637 | if (!(req->flags & REQ_F_APOLL_MULTISHOT)) { |
| @@ -646,7 +646,7 @@ static inline bool io_recv_finish(struct io_kiocb *req, int *ret, · 8 unmodified lines | |||
| 646 | io_recv_prep_retry(req); | 646 | io_recv_prep_retry(req); |
| 647 | /* Known not-empty or unknown state, retry */ | 647 | /* Known not-empty or unknown state, retry */ |
| 648 | if (cflags & IORING_CQE_F_SOCK_NONEMPTY || | 648 | if (cflags & IORING_CQE_F_SOCK_NONEMPTY || |
| 649 | msg->msg_inq == -1U) | 649 | msg->msg_inq == -1) |
| 650 | return false; | 650 | return false; |
| 651 | if (issue_flags & IO_URING_F_MULTISHOT) | 651 | if (issue_flags & IO_URING_F_MULTISHOT) |
| 652 | *ret = IOU_ISSUE_SKIP_COMPLETE; | 652 | *ret = IOU_ISSUE_SKIP_COMPLETE; |
| @@ -805,7 +805,7 @@ retry_multishot: · 152 unmodified lines | |||
| 805 | flags |= MSG_DONTWAIT; | 805 | flags |= MSG_DONTWAIT; |
| 806 | 806 | ||
| 807 | kmsg->msg.msg_get_inq = 1; | 807 | kmsg->msg.msg_get_inq = 1; |
| 808 | kmsg->msg.msg_inq = -1U; | 808 | kmsg->msg.msg_inq = -1; |
| 809 | if (req->flags & REQ_F_APOLL_MULTISHOT) { | 809 | if (req->flags & REQ_F_APOLL_MULTISHOT) { |
| 810 | ret = io_recvmsg_multishot(sock, sr, kmsg, flags, | 810 | ret = io_recvmsg_multishot(sock, sr, kmsg, flags, |
| 811 | &mshot_finished); | 811 | &mshot_finished); |
| @@ -903,7 +903,7 @@ retry_multishot: · 91 unmodified lines | |||
| 903 | if (unlikely(ret)) | 903 | if (unlikely(ret)) |
| 904 | goto out_free; | 904 | goto out_free; |
| 905 | 905 | ||
| 906 | msg.msg_inq = -1U; | 906 | msg.msg_inq = -1; |
| 907 | msg.msg_flags = 0; | 907 | msg.msg_flags = 0; |
| 908 | 908 | ||
| 909 | flags = sr->msg_flags; | 909 | flags = sr->msg_flags; |