
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICSER4 -------------------------------- When recalculating scheduler tunables during CPU hotplug(online/offline), we failed to check and constrain the tunnable parameters within their valid ranges. After repeated operations, this could cause parameters to overflow beyond limits. In extreme cases, sysctl_sched_min_granularity could becomes 0, which disrupts normal scheduler operation and leads to unexpected behavior. Furthermore, setting sysctl_sched_tunable_scaling when this condition exists triggers a division-by-zero error, resulting in a system crash. Fix this by adding proper range checks and constraints during the tunable recalculation process during CPU hotplug events. Fixes: 0bcdcf28c979 ("sched: Fix missing sched tunable recalculation on cpu add/remove") Signed-off-by: Cheng Yu <serein.chengyu@huawei.com> --- include/linux/sched/sysctl.h | 5 +++++ kernel/sched/fair.c | 14 +++++++++----- kernel/sysctl.c | 15 +++++++-------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 90021477ea4c..2bc965928098 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -31,6 +31,11 @@ extern unsigned int sysctl_sched_min_granularity; extern unsigned int sysctl_sched_wakeup_granularity; extern unsigned int sysctl_sched_child_runs_first; +extern unsigned int min_sched_granularity_ns; +extern unsigned int max_sched_granularity_ns; +extern unsigned int min_wakeup_granularity_ns; +extern unsigned int max_wakeup_granularity_ns; + #ifdef CONFIG_QOS_SCHED_DYNAMIC_AFFINITY extern int sysctl_sched_util_low_pct; #endif diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index d48d1ed28a5c..848d45f2bc49 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -235,11 +235,15 @@ static void update_sysctl(void) { unsigned int factor = get_update_sysctl_factor(); -#define SET_SYSCTL(name) \ - (sysctl_##name = (factor) * normalized_sysctl_##name) - SET_SYSCTL(sched_min_granularity); - SET_SYSCTL(sched_latency); - SET_SYSCTL(sched_wakeup_granularity); +#define SET_SYSCTL(name, min_val, max_val) \ + (sysctl_##name = clamp((factor) * normalized_sysctl_##name, \ + min_val, max_val)) + SET_SYSCTL(sched_min_granularity, + min_sched_granularity_ns, max_sched_granularity_ns); + SET_SYSCTL(sched_latency, + min_sched_granularity_ns, max_sched_granularity_ns); + SET_SYSCTL(sched_wakeup_granularity, + min_wakeup_granularity_ns, max_wakeup_granularity_ns); #undef SET_SYSCTL } diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 738d9a4455c1..fdb8146ed5b9 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -192,16 +192,15 @@ static enum sysctl_writes_mode sysctl_writes_strict = SYSCTL_WRITES_STRICT; int sysctl_legacy_va_layout; #endif -#ifdef CONFIG_SCHED_DEBUG -static int min_sched_granularity_ns = 100000; /* 100 usecs */ -static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */ -static int min_wakeup_granularity_ns; /* 0 usecs */ -static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */ -#ifdef CONFIG_SMP +unsigned int min_sched_granularity_ns = 100000; /* 100 usecs */ +unsigned int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */ +unsigned int min_wakeup_granularity_ns; /* 0 usecs */ +unsigned int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */ + +#if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SMP) static int min_sched_tunable_scaling = SCHED_TUNABLESCALING_NONE; static int max_sched_tunable_scaling = SCHED_TUNABLESCALING_END-1; -#endif /* CONFIG_SMP */ -#endif /* CONFIG_SCHED_DEBUG */ +#endif #ifdef CONFIG_COMPACTION static int min_extfrag_threshold; -- 2.25.1