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 | static int io_sqe_buffers_unregister(struct io_ring_ctx *ctx) | 10681 | static int io_sqe_buffers_unregister(struct io_ring_ctx *ctx) |
| 10682 | { | 10682 | { |
| 10683 | unsigned nr = ctx->nr_user_bufs; | ||
| 10683 | int ret; | 10684 | int ret; |
| 10684 | 10685 | ||
| 10685 | if (!ctx->buf_data) | 10686 | if (!ctx->buf_data) |
| 10686 | return -ENXIO; | 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 | ret = io_rsrc_ref_quiesce(ctx->buf_data, ctx); | 10694 | ret = io_rsrc_ref_quiesce(ctx->buf_data, ctx); |
| 10695 | ctx->nr_user_bufs = nr; | ||
| 10689 | if (!ret) | 10696 | if (!ret) |
| 10690 | __io_sqe_buffers_unregister(ctx); | 10697 | __io_sqe_buffers_unregister(ctx); |
| 10691 | return ret; | 10698 | return ret; |