Fixed buffer table quiesce might unlock ->uring_lock, potentially letting new requests to be submitted, don't allow those requests to use the table as they will race with unregistration.
Unified · Split
| @@ -10680,12 +10680,19 @@ static void __io_sqe_buffers_unregister(struct io_ring_ctx *ctx) · 10679 unmodified lines | ||
| 10680 | 10680 | |
| 10681 | 10681 | static int io_sqe_buffers_unregister(struct io_ring_ctx *ctx) |
| 10682 | 10682 | { |
| 10683 | + unsigned nr = ctx->nr_user_bufs; | |
| 10683 | 10684 | int ret; |
| 10684 | 10685 | |
| 10685 | 10686 | if (!ctx->buf_data) |
| 10686 | 10687 | return -ENXIO; |
| 10687 | 10688 | |
| 10689 | + /* | |
| 10690 | + * Quiesce may unlock ->uring_lock, and while it's not held | |
| 10691 | + * prevent new requests using the table. | |
| 10692 | + */ | |
| 10693 | + ctx->nr_user_bufs = 0; | |
| 10688 | 10694 | ret = io_rsrc_ref_quiesce(ctx->buf_data, ctx); |
| 10695 | + ctx->nr_user_bufs = nr; | |
| 10689 | 10696 | if (!ret) |
| 10690 | 10697 | __io_sqe_buffers_unregister(ctx); |
| 10691 | 10698 | return ret; |