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 | 149 | static void io_queue_sqe(struct io_kiocb *req); |
| 150 | 150 | static void io_move_task_work_from_local(struct io_ring_ctx *ctx); |
| 151 | 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 | 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 | 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 | 1268 | void tctx_task_work(struct callback_head *cb) |
| 1242 | 1269 | { |
| 1243 | 1270 | struct io_tw_state ts = {}; |
| @@ -1250,7 +1277,7 @@ void tctx_task_work(struct callback_head *cb) · 6 unmodified lines | ||
| 1250 | 1277 | unsigned int count = 0; |
| 1251 | 1278 | |
| 1252 | 1279 | if (unlikely(current->flags & PF_EXITING)) { |
| 1253 | − io_fallback_tw(tctx); | |
| 1280 | + io_fallback_tw(tctx, true); | |
| 1254 | 1281 | return; |
| 1255 | 1282 | } |
| 1256 | 1283 | |
| @@ -1279,20 +1306,6 @@ void tctx_task_work(struct callback_head *cb) · 22 unmodified lines | ||
| 1279 | 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 | 1309 | static inline void io_req_local_work_add(struct io_kiocb *req, unsigned flags) |
| 1297 | 1310 | { |
| 1298 | 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 | 1372 | if (likely(!task_work_add(req->task, &tctx->task_work, ctx->notify_method))) |
| 1360 | 1373 | return; |
| 1361 | 1374 | |
| 1362 | − io_fallback_tw(tctx); | |
| 1375 | + io_fallback_tw(tctx, false); | |
| 1363 | 1376 | } |
| 1364 | 1377 | |
| 1365 | 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 | 3122 | if (ctx->rings) |
| 3110 | 3123 | io_kill_timeouts(ctx, NULL, true); |
| 3111 | 3124 | |
| 3125 | + flush_delayed_work(&ctx->fallback_work); | |
| 3126 | + | |
| 3112 | 3127 | INIT_WORK(&ctx->exit_work, io_ring_exit_work); |
| 3113 | 3128 | /* |
| 3114 | 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 | 631 | unsigned int cflags; |
| 632 | 632 | |
| 633 | 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 | 635 | cflags |= IORING_CQE_F_SOCK_NONEMPTY; |
| 636 | 636 | |
| 637 | 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 | 646 | io_recv_prep_retry(req); |
| 647 | 647 | /* Known not-empty or unknown state, retry */ |
| 648 | 648 | if (cflags & IORING_CQE_F_SOCK_NONEMPTY || |
| 649 | − msg->msg_inq == -1U) | |
| 649 | + msg->msg_inq == -1) | |
| 650 | 650 | return false; |
| 651 | 651 | if (issue_flags & IO_URING_F_MULTISHOT) |
| 652 | 652 | *ret = IOU_ISSUE_SKIP_COMPLETE; |
| @@ -805,7 +805,7 @@ retry_multishot: · 152 unmodified lines | ||
| 805 | 805 | flags |= MSG_DONTWAIT; |
| 806 | 806 | |
| 807 | 807 | kmsg->msg.msg_get_inq = 1; |
| 808 | − kmsg->msg.msg_inq = -1U; | |
| 808 | + kmsg->msg.msg_inq = -1; | |
| 809 | 809 | if (req->flags & REQ_F_APOLL_MULTISHOT) { |
| 810 | 810 | ret = io_recvmsg_multishot(sock, sr, kmsg, flags, |
| 811 | 811 | &mshot_finished); |
| @@ -903,7 +903,7 @@ retry_multishot: · 91 unmodified lines | ||
| 903 | 903 | if (unlikely(ret)) |
| 904 | 904 | goto out_free; |
| 905 | 905 | |
| 906 | − msg.msg_inq = -1U; | |
| 906 | + msg.msg_inq = -1; | |
| 907 | 907 | msg.msg_flags = 0; |
| 908 | 908 | |
| 909 | 909 | flags = sr->msg_flags; |