Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

io_uring/msg_ring: kill alloc_cache for io_kiocb allocations

A recent commit:

fc582cd26e88 ("io_uring/msg_ring: ensure io_kiocb freeing is deferred for RCU")

fixed an issue with not deferring freeing of io_kiocb structs that
msg_ring allocates to after the current RCU grace period. But this only
covers requests that don't end up in the allocation cache. If a request
goes into the alloc cache, it can get reused before it is sane to do so.
A recent syzbot report would seem to indicate that there's something
there, however it may very well just be because of the KASAN poisoning
that the alloc_cache handles manually.

Rather than attempt to make the alloc_cache sane for that use case, just
drop the usage of the alloc_cache for msg_ring request payload data.

Fixes: 50cf5f3842af ("io_uring/msg_ring: add an alloc cache for io_kiocb entries")
Link: https://lore.kernel.org/io-uring/68cc2687.050a0220.139b6.0005.GAE@google.com/
Reported-by: syzbot+baa2e0f4e02df602583e@syzkaller.appspotmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

+2 -29
-3
include/linux/io_uring_types.h
··· 420 420 struct list_head defer_list; 421 421 unsigned nr_drained; 422 422 423 - struct io_alloc_cache msg_cache; 424 - spinlock_t msg_lock; 425 - 426 423 #ifdef CONFIG_NET_RX_BUSY_POLL 427 424 struct list_head napi_list; /* track busy poll napi_id */ 428 425 spinlock_t napi_lock; /* napi_list lock */
-4
io_uring/io_uring.c
··· 290 290 io_alloc_cache_free(&ctx->netmsg_cache, io_netmsg_cache_free); 291 291 io_alloc_cache_free(&ctx->rw_cache, io_rw_cache_free); 292 292 io_alloc_cache_free(&ctx->cmd_cache, io_cmd_cache_free); 293 - io_alloc_cache_free(&ctx->msg_cache, kfree); 294 293 io_futex_cache_free(ctx); 295 294 io_rsrc_cache_free(ctx); 296 295 } ··· 336 337 ret |= io_alloc_cache_init(&ctx->cmd_cache, IO_ALLOC_CACHE_MAX, 337 338 sizeof(struct io_async_cmd), 338 339 sizeof(struct io_async_cmd)); 339 - spin_lock_init(&ctx->msg_lock); 340 - ret |= io_alloc_cache_init(&ctx->msg_cache, IO_ALLOC_CACHE_MAX, 341 - sizeof(struct io_kiocb), 0); 342 340 ret |= io_futex_cache_init(ctx); 343 341 ret |= io_rsrc_cache_init(ctx); 344 342 if (ret)
+2 -22
io_uring/msg_ring.c
··· 11 11 #include "io_uring.h" 12 12 #include "rsrc.h" 13 13 #include "filetable.h" 14 - #include "alloc_cache.h" 15 14 #include "msg_ring.h" 16 15 17 16 /* All valid masks for MSG_RING */ ··· 75 76 struct io_ring_ctx *ctx = req->ctx; 76 77 77 78 io_add_aux_cqe(ctx, req->cqe.user_data, req->cqe.res, req->cqe.flags); 78 - if (spin_trylock(&ctx->msg_lock)) { 79 - if (io_alloc_cache_put(&ctx->msg_cache, req)) 80 - req = NULL; 81 - spin_unlock(&ctx->msg_lock); 82 - } 83 - if (req) 84 - kfree_rcu(req, rcu_head); 79 + kfree_rcu(req, rcu_head); 85 80 percpu_ref_put(&ctx->refs); 86 81 } 87 82 ··· 97 104 return 0; 98 105 } 99 106 100 - static struct io_kiocb *io_msg_get_kiocb(struct io_ring_ctx *ctx) 101 - { 102 - struct io_kiocb *req = NULL; 103 - 104 - if (spin_trylock(&ctx->msg_lock)) { 105 - req = io_alloc_cache_get(&ctx->msg_cache); 106 - spin_unlock(&ctx->msg_lock); 107 - if (req) 108 - return req; 109 - } 110 - return kmem_cache_alloc(req_cachep, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO); 111 - } 112 - 113 107 static int io_msg_data_remote(struct io_ring_ctx *target_ctx, 114 108 struct io_msg *msg) 115 109 { 116 110 struct io_kiocb *target; 117 111 u32 flags = 0; 118 112 119 - target = io_msg_get_kiocb(target_ctx); 113 + target = kmem_cache_alloc(req_cachep, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO) ; 120 114 if (unlikely(!target)) 121 115 return -ENOMEM; 122 116