History

io_uring: check if we need to reschedule during overflow flush

In terms of normal application usage, this list will always be empty. And if an application does overflow a bit, it'll have a few entries. However, nothing obviously prevents syzbot from running a test case that generates a ton of overflow entries, and then flushing them can take quite a while. Check for needing to reschedule while flushing, and drop our locks and do so if necessary. There's no state to maintain here as overflows always prune from head-of-list, hence it's fine to drop and reacquire the locks at the end of the loop.

Jens Axboe committed 2 years ago

Commit eac2ca21 parent eed138d1 file · +15 −0Browse files

Unified · Split

io_uring/io_uring.c+15−0
@@ -624,6 +624,21 @@ static void __io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool dying) · 623 unmodified lines
624 }624 }
625 list_del(&ocqe->list);625 list_del(&ocqe->list);
626 kfree(ocqe);626 kfree(ocqe);
627
628 /*
629 * For silly syzbot cases that deliberately overflow by huge
630 * amounts, check if we need to resched and drop and
631 * reacquire the locks if so. Nothing real would ever hit this.
632 * Ideally we'd have a non-posting unlock for this, but hard
633 * to care for a non-real case.
634 */
635 if (need_resched()) {
636 io_cq_unlock_post(ctx);
637 mutex_unlock(&ctx->uring_lock);
638 cond_resched();
639 mutex_lock(&ctx->uring_lock);
640 io_cq_lock(ctx);
641 }
627 }642 }
628 643
629 if (list_empty(&ctx->cq_overflow_list)) {644 if (list_empty(&ctx->cq_overflow_list)) {