diff --git a/lisa/_assets/kmodules/sched_tp/features.c b/lisa/_assets/kmodules/sched_tp/features.c index 36b2252671c49519ec4995612e29bb9eeee7c3e8..ee253288bb4a5750092c4b7547e1582232c35e17 100644 --- a/lisa/_assets/kmodules/sched_tp/features.c +++ b/lisa/_assets/kmodules/sched_tp/features.c @@ -13,13 +13,15 @@ int __enable_feature(struct feature* feature) { mutex_lock(feature->lock); if (feature->enabled) { - ret = 0; + ret = feature->__enable_ret; } else { pr_info("Enabling lisa feature %s\n", feature->name); if (feature->enable) ret = feature->enable(feature); else ret = 0; + feature->__enable_ret = ret; + if (ret) pr_err("Failed to enable feature %s: %i", feature->name, ret); } @@ -76,9 +78,7 @@ static int __process_features(char **selected, size_t selected_len, feature_proc int ret = 0; for (feature=__lisa_features_start; feature < __lisa_features_stop; feature++) { - ret = __select_feature(feature, selected, selected_len, process); - if (ret) - return ret; + ret |= __select_feature(feature, selected, selected_len, process); } return ret; } @@ -98,6 +98,8 @@ static int __enable_feature_explicitly(struct feature* feature) { } int init_features(char **selected, size_t selected_len) { + BUG_ON(MAX_FEATURES < ((__lisa_features_stop - __lisa_features_start) / sizeof(struct feature))); + pr_info("Available features: "); __process_features(NULL, 0, __list_feature); pr_info("\n"); @@ -106,16 +108,14 @@ int init_features(char **selected, size_t selected_len) { static int __disable_explicitly_enabled_feature(struct feature* feature) { bool selected; - - BUG_ON(MAX_FEATURES < ((__lisa_features_stop - __lisa_features_start) / sizeof(struct feature))); + int ret = 0; mutex_lock(feature->lock); selected = feature->__explicitly_enabled; mutex_unlock(feature->lock); if (selected) - __disable_feature(feature); - /* Always return 0 to avoid the early return of __process_features() */ - return 0; + ret |= __disable_feature(feature); + return ret; } int deinit_features(void) { diff --git a/lisa/_assets/kmodules/sched_tp/features.h b/lisa/_assets/kmodules/sched_tp/features.h index 973bc7144ab59670499a96c352d2f2b01d34d890..b17411f5cb85dfd151021318bc1210a8d48e3ea3 100644 --- a/lisa/_assets/kmodules/sched_tp/features.h +++ b/lisa/_assets/kmodules/sched_tp/features.h @@ -31,6 +31,9 @@ struct feature { int (*enable)(struct feature*); int (*disable)(struct feature*); + /* Return code of the enable() function */ + int __enable_ret; + /* true if the feature has been explicitly enabled by the user */ bool __explicitly_enabled; /* true if the feature is internal, i.e. not exposed to the user. @@ -68,6 +71,7 @@ int __placeholder_deinit(struct feature *feature); .disable = __placeholder_deinit, \ .lock = &__lisa_mutex_feature_##feature_name, \ .__internal = true, \ + .__enable_ret = 0, \ }; #define __DEFINE_FEATURE_STRONG(feature_name, enable_f, disable_f, internal) \ @@ -81,6 +85,7 @@ int __placeholder_deinit(struct feature *feature); .disable = disable_f, \ .lock = &__lisa_mutex_feature_##feature_name, \ .__internal = internal, \ + .__enable_ret = 0, \ }; /** diff --git a/lisa/_assets/kmodules/sched_tp/main.c b/lisa/_assets/kmodules/sched_tp/main.c index 46ad99f3b605411c02117dde6c7c430b0f18d1c0..446ccdbdedbd49205b96e95b0e90f549a4b7074a 100644 --- a/lisa/_assets/kmodules/sched_tp/main.c +++ b/lisa/_assets/kmodules/sched_tp/main.c @@ -11,27 +11,36 @@ module_param_array(features, charp, &features_len, 0); MODULE_PARM_DESC(features, "Comma-separated list of features to enable. Available features are printed when loading the module"); static void modexit(void) { - deinit_features(); + if (deinit_features()) + pr_err("Some errors happened while unloading LISA kernel module\n"); } static int __init modinit(void) { - int ret = 0; - ret |= init_features(features, features_len); + int ret = init_features(features, features_len); - /* Use one of the standard error code */ - if (ret) - ret = -EINVAL; - - /* Call modexit() explicitly, since it will not be called when ret != 0. - * Not calling modexit() can (and will) result in kernel panic handlers - * installed by the module are not deregistered before the module code - * vanishes. - */ if (ret) { pr_err("Some errors happened while loading LISA kernel module\n"); - modexit(); + + /* Use one of the standard error code */ + ret = -EINVAL; + + /* If the user selected features manually, make module loading fail so + * that they are aware that things went wrong. Otherwise, just + * keep going as the user just wanted to enable as many features + * as possible. + */ + if (features_len) { + /* Call modexit() explicitly, since it will not be called when ret != 0. + * Not calling modexit() can (and will) result in kernel panic handlers + * installed by the module are not deregistered before the module code + * vanishes. + */ + modexit(); + return ret; + + } } - return ret; + return 0; } module_init(modinit); diff --git a/lisa/_assets/kmodules/sched_tp/sched_helpers.h b/lisa/_assets/kmodules/sched_tp/sched_helpers.h index 424fbfa6183da3f9059bb47947ffeccbd5d64e35..6305cefcda4d7cd8e576e315ba89da164fd752ec 100644 --- a/lisa/_assets/kmodules/sched_tp/sched_helpers.h +++ b/lisa/_assets/kmodules/sched_tp/sched_helpers.h @@ -44,7 +44,7 @@ static inline bool task_group_is_autogroup(struct task_group *tg) #endif } -int autogroup_path(struct task_group *tg, char *buf, int buflen) +static int autogroup_path(struct task_group *tg, char *buf, int buflen) { #ifdef CONFIG_SCHED_AUTOGROUP if (!task_group_is_autogroup(tg))