Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions configure.d/1_kvmalloc.conf
Original file line number Diff line number Diff line change
@@ -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 <linux/sched/mm.h>
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 $@
14 changes: 14 additions & 0 deletions modules/cas_cache/ocf_env.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion ocf
Loading