diff options
author | Jens Axboe <axboe@kernel.dk> | 2024-09-30 17:11:32 -0600 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2024-10-29 13:43:27 -0600 |
commit | b6b3eb19dd86ecc3f188bd419f12cdfcfbeda5e7 (patch) | |
tree | 6f725618095e97539ce449bf169796e48ae0e430 /io_uring/io_uring.c | |
parent | 8abf47a8d61c9e8314ae4cfa27e18c8df67c37bc (diff) |
io_uring: move cancel hash tables to kvmalloc/kvfree
Convert to using kvmalloc/kfree() for the hash tables, and while at it,
make it handle low memory situations better.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'io_uring/io_uring.c')
-rw-r--r-- | io_uring/io_uring.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 6aac72b2958f..d7ad4ea5f40b 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -261,13 +261,19 @@ static __cold void io_fallback_req_func(struct work_struct *work) static int io_alloc_hash_table(struct io_hash_table *table, unsigned bits) { - unsigned hash_buckets = 1U << bits; - size_t hash_size = hash_buckets * sizeof(table->hbs[0]); + unsigned int hash_buckets; int i; - table->hbs = kmalloc(hash_size, GFP_KERNEL); - if (!table->hbs) - return -ENOMEM; + do { + hash_buckets = 1U << bits; + table->hbs = kvmalloc_array(hash_buckets, sizeof(table->hbs[0]), + GFP_KERNEL_ACCOUNT); + if (table->hbs) + break; + if (bits == 1) + return -ENOMEM; + bits--; + } while (1); table->hash_bits = bits; for (i = 0; i < hash_buckets; i++) @@ -360,7 +366,7 @@ err: io_alloc_cache_free(&ctx->uring_cache, kfree); io_alloc_cache_free(&ctx->msg_cache, io_msg_cache_free); io_futex_cache_free(ctx); - kfree(ctx->cancel_table.hbs); + kvfree(ctx->cancel_table.hbs); xa_destroy(&ctx->io_bl_xa); kfree(ctx); return NULL; @@ -2772,7 +2778,7 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx) if (ctx->hash_map) io_wq_put_hash(ctx->hash_map); io_napi_free(ctx); - kfree(ctx->cancel_table.hbs); + kvfree(ctx->cancel_table.hbs); xa_destroy(&ctx->io_bl_xa); kfree(ctx); } |