From aa660ca0a57dd924d80c7f3f522ec60bc006d4d3 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Wed, 12 Mar 2025 13:14:15 +0100 Subject: [PATCH 1/2] Implement involuntary preemption check Prevent loading the kernel module if the kernel can be involuntarily preempted CAS will work if the kernel has been compiled with either CONFIG_PREEMPT_NONE, CONFIG_PREEMPT_VOLUNTARY, or CONFIG_PREEMPT_DYNAMIC. If the dynamic configuration is enabled, the kernel must be booted with preempt=none or preempt=voluntary. Signed-off-by: Michal Mielewczyk --- modules/cas_cache/main.c | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/modules/cas_cache/main.c b/modules/cas_cache/main.c index 5453a51..1305ca9 100644 --- a/modules/cas_cache/main.c +++ b/modules/cas_cache/main.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2022 Intel Corporation +* Copyright(c) 2025 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -42,10 +43,59 @@ MODULE_PARM_DESC(seq_cut_off_mb, ocf_ctx_t cas_ctx; struct cas_module cas_module; +static inline uint32_t involuntary_preemption_enabled(void) +{ + bool config_dynamic = IS_ENABLED(CONFIG_PREEMPT_DYNAMIC); + bool config_rt = IS_ENABLED(CONFIG_PREEMPT_RT); + bool config_preempt = IS_ENABLED(CONFIG_PREEMPT); + bool config_lazy = IS_ENABLED(CONFIG_PREEMPT_LAZY); + bool config_none = IS_ENABLED(CONFIG_PREEMPT_NONE); + + if (!config_dynamic && !config_rt && !config_preempt && !config_lazy) + return false; + + if (config_none) + return false; + + if (config_rt || config_preempt || config_lazy) { + printk(KERN_ERR OCF_PREFIX_SHORT + "The kernel has been built with involuntary preemption " + "enabled.\nFailed to load Open CAS kernel module.\n"); + return true; + } + +#ifdef CONFIG_PREEMPT_DYNAMIC + /* preempt_model_none() or preempt_model_voluntary() are not defined if + * the kernel has been compiled without PREEMPT_DYNAMIC + */ + printk(KERN_WARNING OCF_PREFIX_SHORT + "The kernel has been compiled with preemption configurable\n" + "at boot time (PREEMPT_DYNAMIC=y). Open CAS doesn't support\n" + "kernels with involuntary preemption so make sure to set\n" + "\"preempt=\" to \"none\" or \"voluntary\" in the kernel" + " command line\n"); + + if (!preempt_model_none() && !preempt_model_voluntary()) { + printk(KERN_ERR OCF_PREFIX_SHORT + "The kernel has been booted with involuntary " + "preemption enabled.\nFailed to load Open CAS kernel " + "module.\n"); + return true; + } else { + return false; + } +#endif + + return false; +} + static int __init cas_init_module(void) { int result = 0; + if (involuntary_preemption_enabled()) + return -ENOTSUP; + if (!writeback_queue_unblock_size || !max_writeback_queue_size) { printk(KERN_ERR OCF_PREFIX_SHORT "Invalid module parameter.\n"); From 0f23ae6950bb26bc1b6c947eede4984c4b5f1f89 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Wed, 19 Mar 2025 12:18:34 +0100 Subject: [PATCH 2/2] Makefile: Error handling for failed modprobe Print an additional error message and remove the installed kernel module Signed-off-by: Michal Mielewczyk --- modules/Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/Makefile b/modules/Makefile index 5c376fb..bb2214d 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -1,5 +1,6 @@ # # Copyright(c) 2012-2022 Intel Corporation +# Copyright(c) 2025 Huawei Technologies # SPDX-License-Identifier: BSD-3-Clause # # If $(M) is defined, we've been invoked from the @@ -52,7 +53,11 @@ distclean: clean distsync install: install_files @$(DEPMOD) - @$(MODPROBE) $(CACHE_MODULE) + @$(MODPROBE) $(CACHE_MODULE) || ( \ + echo "See dmesg for more information" >&2 && \ + rm -f $(DESTDIR)$(MODULES_DIR)/$(CACHE_MODULE).ko && exit 1 \ + ) + install_files: @echo "Installing Open-CAS modules"