From f4ae963892e61069219310e3f029ee44e5cd0ff1 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 28 Sep 2026 00:29:56 +0200 Subject: [PATCH] req: Use kvzalloc() for allocating request map For a large requests (several MiB and up) zalloc() has a huge chance to fail if the system memory is fragmented, causing I/O error. Prevent this error by using kvzalloc(), which internally first attempts zalloc(), and it it fails, falls back to vzmalloc(). For requests of that size the latency of the I/O itself is large enough for additional vmalloc allocation to not matter anyway, and for small requests we still have fast mempool/kmalloc path with a fallback. Signed-off-by: Robert Baldyga --- env/posix/ocf_env_default.h | 10 ++++++++++ src/ocf_request.c | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/env/posix/ocf_env_default.h b/env/posix/ocf_env_default.h index 956a27dc..41c090be 100644 --- a/env/posix/ocf_env_default.h +++ b/env/posix/ocf_env_default.h @@ -140,6 +140,16 @@ static inline void env_free(const void *ptr) free((void *)ptr); } +static inline void *env_kvzalloc(size_t size, int flags) +{ + return env_zalloc(size, 0); +} + +static inline void env_kvfree(const void *ptr) +{ + free((void *)ptr); +} + static inline void *env_vmalloc_flags(size_t size, int flags) { return malloc(size); diff --git a/src/ocf_request.c b/src/ocf_request.c index c6b76ab9..2be21d3c 100644 --- a/src/ocf_request.c +++ b/src/ocf_request.c @@ -315,7 +315,7 @@ int ocf_req_alloc_map(struct ocf_request *req) if (req->map) return 0; - req->map = env_zalloc(ocf_req_sizeof_map(lines) + + req->map = env_kvzalloc(ocf_req_sizeof_map(lines) + ocf_req_sizeof_alock_status(req->core_line_count), ENV_MEM_NOIO); if (!req->map) { @@ -402,7 +402,7 @@ void ocf_req_put(struct ocf_request *req) env_free(req); } else { if (req->map != req->__map) - env_free(req->map); + env_kvfree(req->map); env_mpool_del(req->cache->owner->resources.req, req, req->alloc_core_line_count); }