On 11/7/19 2:53 AM, Pavel Begunkov wrote: >> @@ -804,8 +803,10 @@ static void io_fail_links(struct io_kiocb *req) >> link->submit.sqe->opcode == IORING_OP_LINK_TIMEOUT) { >> io_link_cancel_timeout(ctx, link); >> } else { >> - io_cqring_fill_event(ctx, link->user_data, -ECANCELED); >> - __io_free_req(link); >> + io_cqring_fill_event(link, -ECANCELED); >> + /* drop both submit and complete references */ >> + io_put_req(link, NULL); >> + io_put_req(link, NULL); > > io_put_req() -> ... -> io_free_req() -> io_fail_links() -> io_put_req() > > It shouldn't recurse further, but probably it would be better to avoid > it at all. Not sure how to improve that. We could do something ala: if (refcount_sub_and_test(2, &link->refs)) __io_free_req(link); to make it clear and more resistant against recursion. I also think we need to put that link path out-of-line in io_free_req(). I'll make those two changes. -- Jens Axboe