diff --git a/configure.d/1_kvmalloc.conf b/configure.d/1_kvmalloc.conf new file mode 100644 index 000000000..99127b2cb --- /dev/null +++ b/configure.d/1_kvmalloc.conf @@ -0,0 +1,68 @@ +#!/bin/bash +# +# Copyright(c) 2026 Unvertical +# SPDX-License-Identifier: BSD-3-Clause +# + +. $(dirname $3)/conf_framework.sh + +# kvmalloc() supports GFP_NOIO (i.e. falls back to vmalloc() with NOIO +# semantics) since commit a421ef303008 ("mm: allow !GFP_KERNEL allocations +# for kvmalloc"), v5.17. It's a behavioral change, not detectable directly, +# but the very same commit dropped ceph_kvmalloc(), so use it as a marker. +# ceph_kvmalloc() isn't exported, so only check its declaration (typeof +# doesn't emit a symbol reference that modpost would reject). +# Default to the memalloc scope variant, as it's correct on every kernel. +check() { + cur_name=$(basename $2) + config_file_path=$1 + if compile_module $cur_name "__typeof__(&ceph_kvmalloc) f = NULL; (void)f;" "linux/ceph/libceph.h" + then + echo $cur_name "2" >> $config_file_path + elif compile_module $cur_name "struct ceph_client *c = NULL; (void)c;" "linux/ceph/libceph.h" + then + echo $cur_name "1" >> $config_file_path + else + echo $cur_name "2" >> $config_file_path + fi +} + +apply() { + case "$1" in + "1") + add_function " + static inline void *cas_kvzalloc(size_t size, gfp_t flags) + { + return kvzalloc(size, flags); + }" ;; + "2") + add_function " +#include + static inline void *cas_kvzalloc(size_t size, gfp_t flags) + { + unsigned int memalloc_flags; + void *ptr; + + if ((flags & (__GFP_IO | __GFP_FS)) == (__GFP_IO | __GFP_FS)) + return kvzalloc(size, flags); + + if (flags & __GFP_IO) + memalloc_flags = memalloc_nofs_save(); + else + memalloc_flags = memalloc_noio_save(); + + ptr = kvzalloc(size, GFP_KERNEL); + + if (flags & __GFP_IO) + memalloc_nofs_restore(memalloc_flags); + else + memalloc_noio_restore(memalloc_flags); + + return ptr; + }" ;; + *) + exit 1 + esac +} + +conf_run $@ diff --git a/modules/cas_cache/ocf_env.h b/modules/cas_cache/ocf_env.h index c6bcd488b..83d813a35 100644 --- a/modules/cas_cache/ocf_env.h +++ b/modules/cas_cache/ocf_env.h @@ -42,6 +42,20 @@ static inline void env_free(const void *ptr) kfree(ptr); } +/* + * Try a physically contiguous allocation first and fall back to vmalloc() + * if that fails. + */ +static inline void *env_kvzalloc(size_t size, int flags) +{ + return cas_kvzalloc(size, flags); +} + +static inline void env_kvfree(const void *ptr) +{ + kvfree(ptr); +} + static inline void *env_vmalloc_flags(size_t size, int flags) { return cas_vmalloc(size, flags | __GFP_HIGHMEM); diff --git a/ocf b/ocf index 68233d409..aff886fcd 160000 --- a/ocf +++ b/ocf @@ -1 +1 @@ -Subproject commit 68233d40999d5c31fb63e4a055286a233c050d13 +Subproject commit aff886fcde4e0ae32c856ba2fb00529157a8ad2d