io_uring/kbuf: protect io_buffer_list teardown with a reference
commit 6b69c4ab4f685327d9e10caf0d84217ba23a8c4b upstream. No functional changes in this patch, just in preparation for being able to keep the buffer list alive outside of the ctx->uring_lock. Cc: stable@vger.kernel.org # v6.4+ Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
4c0a5da0e7
commit
b392402d29
@ -59,6 +59,7 @@ static int io_buffer_add_list(struct io_ring_ctx *ctx,
|
||||
* always under the ->uring_lock, but the RCU lookup from mmap does.
|
||||
*/
|
||||
bl->bgid = bgid;
|
||||
atomic_set(&bl->refs, 1);
|
||||
return xa_err(xa_store(&ctx->io_bl_xa, bgid, bl, GFP_KERNEL));
|
||||
}
|
||||
|
||||
@ -272,6 +273,14 @@ static int __io_remove_buffers(struct io_ring_ctx *ctx,
|
||||
return i;
|
||||
}
|
||||
|
||||
static void io_put_bl(struct io_ring_ctx *ctx, struct io_buffer_list *bl)
|
||||
{
|
||||
if (atomic_dec_and_test(&bl->refs)) {
|
||||
__io_remove_buffers(ctx, bl, -1U);
|
||||
kfree_rcu(bl, rcu);
|
||||
}
|
||||
}
|
||||
|
||||
void io_destroy_buffers(struct io_ring_ctx *ctx)
|
||||
{
|
||||
struct io_buffer_list *bl;
|
||||
@ -279,8 +288,7 @@ void io_destroy_buffers(struct io_ring_ctx *ctx)
|
||||
|
||||
xa_for_each(&ctx->io_bl_xa, index, bl) {
|
||||
xa_erase(&ctx->io_bl_xa, bl->bgid);
|
||||
__io_remove_buffers(ctx, bl, -1U);
|
||||
kfree_rcu(bl, rcu);
|
||||
io_put_bl(ctx, bl);
|
||||
}
|
||||
|
||||
while (!list_empty(&ctx->io_buffers_pages)) {
|
||||
@ -676,9 +684,8 @@ int io_unregister_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
|
||||
if (!bl->is_mapped)
|
||||
return -EINVAL;
|
||||
|
||||
__io_remove_buffers(ctx, bl, -1U);
|
||||
xa_erase(&ctx->io_bl_xa, bl->bgid);
|
||||
kfree_rcu(bl, rcu);
|
||||
io_put_bl(ctx, bl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,8 @@ struct io_buffer_list {
|
||||
__u16 head;
|
||||
__u16 mask;
|
||||
|
||||
atomic_t refs;
|
||||
|
||||
/* ring mapped provided buffers */
|
||||
__u8 is_mapped;
|
||||
/* ring mapped provided buffers, but mmap'ed by application */
|
||||
|
Loading…
x
Reference in New Issue
Block a user