Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'io_uring-5.8-2020-07-24' of git://git.kernel.dk/linux-block into master

Pull io_uring fixes from Jens Axboe:

- Fix discrepancy in how sqe->flags are treated for a few requests,
this makes it consistent (Daniele)

- Ensure that poll driven retry works with double waitqueue poll users

- Fix a missing io_req_init_async() (Pavel)

* tag 'io_uring-5.8-2020-07-24' of git://git.kernel.dk/linux-block:
io_uring: missed req_init_async() for IOSQE_ASYNC
io_uring: always allow drain/link/hardlink/async sqe flags
io_uring: ensure double poll additions work with both request types

+36 -25
+36 -25
fs/io_uring.c
··· 605 605 606 606 struct async_poll { 607 607 struct io_poll_iocb poll; 608 + struct io_poll_iocb *double_poll; 608 609 struct io_wq_work work; 609 610 }; 610 611 ··· 4160 4159 return false; 4161 4160 } 4162 4161 4163 - static void io_poll_remove_double(struct io_kiocb *req) 4162 + static void io_poll_remove_double(struct io_kiocb *req, void *data) 4164 4163 { 4165 - struct io_poll_iocb *poll = (struct io_poll_iocb *) req->io; 4164 + struct io_poll_iocb *poll = data; 4166 4165 4167 4166 lockdep_assert_held(&req->ctx->completion_lock); 4168 4167 ··· 4182 4181 { 4183 4182 struct io_ring_ctx *ctx = req->ctx; 4184 4183 4185 - io_poll_remove_double(req); 4184 + io_poll_remove_double(req, req->io); 4186 4185 req->poll.done = true; 4187 4186 io_cqring_fill_event(req, error ? error : mangle_poll(mask)); 4188 4187 io_commit_cqring(ctx); ··· 4225 4224 int sync, void *key) 4226 4225 { 4227 4226 struct io_kiocb *req = wait->private; 4228 - struct io_poll_iocb *poll = (struct io_poll_iocb *) req->io; 4227 + struct io_poll_iocb *poll = req->apoll->double_poll; 4229 4228 __poll_t mask = key_to_poll(key); 4230 4229 4231 4230 /* for instances that support it check for an event match first: */ 4232 4231 if (mask && !(mask & poll->events)) 4233 4232 return 0; 4234 4233 4235 - if (req->poll.head) { 4234 + if (poll && poll->head) { 4236 4235 bool done; 4237 4236 4238 - spin_lock(&req->poll.head->lock); 4239 - done = list_empty(&req->poll.wait.entry); 4237 + spin_lock(&poll->head->lock); 4238 + done = list_empty(&poll->wait.entry); 4240 4239 if (!done) 4241 - list_del_init(&req->poll.wait.entry); 4242 - spin_unlock(&req->poll.head->lock); 4240 + list_del_init(&poll->wait.entry); 4241 + spin_unlock(&poll->head->lock); 4243 4242 if (!done) 4244 4243 __io_async_wake(req, poll, mask, io_poll_task_func); 4245 4244 } ··· 4259 4258 } 4260 4259 4261 4260 static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt, 4262 - struct wait_queue_head *head) 4261 + struct wait_queue_head *head, 4262 + struct io_poll_iocb **poll_ptr) 4263 4263 { 4264 4264 struct io_kiocb *req = pt->req; 4265 4265 ··· 4271 4269 */ 4272 4270 if (unlikely(poll->head)) { 4273 4271 /* already have a 2nd entry, fail a third attempt */ 4274 - if (req->io) { 4272 + if (*poll_ptr) { 4275 4273 pt->error = -EINVAL; 4276 4274 return; 4277 4275 } ··· 4283 4281 io_init_poll_iocb(poll, req->poll.events, io_poll_double_wake); 4284 4282 refcount_inc(&req->refs); 4285 4283 poll->wait.private = req; 4286 - req->io = (void *) poll; 4284 + *poll_ptr = poll; 4287 4285 } 4288 4286 4289 4287 pt->error = 0; ··· 4295 4293 struct poll_table_struct *p) 4296 4294 { 4297 4295 struct io_poll_table *pt = container_of(p, struct io_poll_table, pt); 4296 + struct async_poll *apoll = pt->req->apoll; 4298 4297 4299 - __io_queue_proc(&pt->req->apoll->poll, pt, head); 4298 + __io_queue_proc(&apoll->poll, pt, head, &apoll->double_poll); 4300 4299 } 4301 4300 4302 4301 static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx) ··· 4347 4344 } 4348 4345 } 4349 4346 4347 + io_poll_remove_double(req, apoll->double_poll); 4350 4348 spin_unlock_irq(&ctx->completion_lock); 4351 4349 4352 4350 /* restore ->work in case we need to retry again */ 4353 4351 if (req->flags & REQ_F_WORK_INITIALIZED) 4354 4352 memcpy(&req->work, &apoll->work, sizeof(req->work)); 4353 + kfree(apoll->double_poll); 4355 4354 kfree(apoll); 4356 4355 4357 4356 if (!canceled) { ··· 4441 4436 struct async_poll *apoll; 4442 4437 struct io_poll_table ipt; 4443 4438 __poll_t mask, ret; 4444 - bool had_io; 4445 4439 4446 4440 if (!req->file || !file_can_poll(req->file)) 4447 4441 return false; ··· 4452 4448 apoll = kmalloc(sizeof(*apoll), GFP_ATOMIC); 4453 4449 if (unlikely(!apoll)) 4454 4450 return false; 4451 + apoll->double_poll = NULL; 4455 4452 4456 4453 req->flags |= REQ_F_POLLED; 4457 4454 if (req->flags & REQ_F_WORK_INITIALIZED) 4458 4455 memcpy(&apoll->work, &req->work, sizeof(req->work)); 4459 - had_io = req->io != NULL; 4460 4456 4461 4457 io_get_req_task(req); 4462 4458 req->apoll = apoll; ··· 4474 4470 ret = __io_arm_poll_handler(req, &apoll->poll, &ipt, mask, 4475 4471 io_async_wake); 4476 4472 if (ret) { 4477 - ipt.error = 0; 4478 - /* only remove double add if we did it here */ 4479 - if (!had_io) 4480 - io_poll_remove_double(req); 4473 + io_poll_remove_double(req, apoll->double_poll); 4481 4474 spin_unlock_irq(&ctx->completion_lock); 4482 4475 if (req->flags & REQ_F_WORK_INITIALIZED) 4483 4476 memcpy(&req->work, &apoll->work, sizeof(req->work)); 4477 + kfree(apoll->double_poll); 4484 4478 kfree(apoll); 4485 4479 return false; 4486 4480 } ··· 4509 4507 bool do_complete; 4510 4508 4511 4509 if (req->opcode == IORING_OP_POLL_ADD) { 4512 - io_poll_remove_double(req); 4510 + io_poll_remove_double(req, req->io); 4513 4511 do_complete = __io_poll_remove_one(req, &req->poll); 4514 4512 } else { 4515 4513 struct async_poll *apoll = req->apoll; 4514 + 4515 + io_poll_remove_double(req, apoll->double_poll); 4516 4516 4517 4517 /* non-poll requests have submit ref still */ 4518 4518 do_complete = __io_poll_remove_one(req, &apoll->poll); ··· 4528 4524 if (req->flags & REQ_F_WORK_INITIALIZED) 4529 4525 memcpy(&req->work, &apoll->work, 4530 4526 sizeof(req->work)); 4527 + kfree(apoll->double_poll); 4531 4528 kfree(apoll); 4532 4529 } 4533 4530 } ··· 4629 4624 { 4630 4625 struct io_poll_table *pt = container_of(p, struct io_poll_table, pt); 4631 4626 4632 - __io_queue_proc(&pt->req->poll, pt, head); 4627 + __io_queue_proc(&pt->req->poll, pt, head, (struct io_poll_iocb **) &pt->req->io); 4633 4628 } 4634 4629 4635 4630 static int io_poll_add_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ··· 4737 4732 { 4738 4733 if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) 4739 4734 return -EINVAL; 4740 - if (sqe->flags || sqe->ioprio || sqe->buf_index || sqe->len) 4735 + if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) 4736 + return -EINVAL; 4737 + if (sqe->ioprio || sqe->buf_index || sqe->len) 4741 4738 return -EINVAL; 4742 4739 4743 4740 req->timeout.addr = READ_ONCE(sqe->addr); ··· 4917 4910 { 4918 4911 if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) 4919 4912 return -EINVAL; 4920 - if (sqe->flags || sqe->ioprio || sqe->off || sqe->len || 4921 - sqe->cancel_flags) 4913 + if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) 4914 + return -EINVAL; 4915 + if (sqe->ioprio || sqe->off || sqe->len || sqe->cancel_flags) 4922 4916 return -EINVAL; 4923 4917 4924 4918 req->cancel.addr = READ_ONCE(sqe->addr); ··· 4937 4929 static int io_files_update_prep(struct io_kiocb *req, 4938 4930 const struct io_uring_sqe *sqe) 4939 4931 { 4940 - if (sqe->flags || sqe->ioprio || sqe->rw_flags) 4932 + if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) 4933 + return -EINVAL; 4934 + if (sqe->ioprio || sqe->rw_flags) 4941 4935 return -EINVAL; 4942 4936 4943 4937 req->files_update.offset = READ_ONCE(sqe->off); ··· 5730 5720 * Never try inline submit of IOSQE_ASYNC is set, go straight 5731 5721 * to async execution. 5732 5722 */ 5723 + io_req_init_async(req); 5733 5724 req->work.flags |= IO_WQ_WORK_CONCURRENT; 5734 5725 io_queue_async_work(req); 5735 5726 } else {