hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I9NR7Q CVE: NA
--------------------------------
If we set isolcpus without CPU0, it will print the following error: [ 0.000000] Housekeeping: must include one present CPU, using boot CPU:0 It is because when string 'isolcpus=xxx' is parsed, only CPU0 is set as present for arch arm64.
Unlike X86 and PowerPC, the present_cpu_mask is set rather late in smp_prepare_cpus() for arm64. In CPU hotplug situation, some possible CPUs are not marked as present, only CPUs with its GICC marked as ACPI_MADT_ENABLED are marked as present. So we cannot set preset_cpu_mask for all possible CPUs at early stage.
Only check cpu_present_mask cannot assure that the CPUs will be broughtup online, as described in the below Link1. So do not check whether housekeeping CPUs are present when parsing 'isolcpus'. A following commit will add check after CPU online process is finished, as suggested in below Link2.
Link1: https://lore.kernel.org/all/20190504002733.GB19076@lenoir/ Link2: https://lore.kernel.org/all/1557186148.ocs72ssdjc.astroid@bobo.none/ Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com --- include/linux/sched/isolation.h | 3 +++ kernel/sched/isolation.c | 26 ++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/include/linux/sched/isolation.h b/include/linux/sched/isolation.h index 2f93081ad7a0..3c571c32dbbd 100644 --- a/include/linux/sched/isolation.h +++ b/include/linux/sched/isolation.h @@ -19,6 +19,7 @@ enum hk_flags {
#ifdef CONFIG_CPU_ISOLATION extern bool enhanced_isolcpus; +extern bool support_cpu0_nohz_full; DECLARE_STATIC_KEY_FALSE(housekeeping_overridden); extern int housekeeping_any_cpu(enum hk_flags flags); extern const struct cpumask *housekeeping_cpumask(enum hk_flags flags); @@ -30,6 +31,8 @@ extern void __init housekeeping_init(void); #else
#define enhanced_isolcpus 0 +#define support_cpu0_nohz_full 0 + static inline int housekeeping_any_cpu(enum hk_flags flags) { return smp_processor_id(); diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c index 785ef5201116..f9a8c7d53acc 100644 --- a/kernel/sched/isolation.c +++ b/kernel/sched/isolation.c @@ -13,6 +13,7 @@ DEFINE_STATIC_KEY_FALSE(housekeeping_overridden); EXPORT_SYMBOL_GPL(housekeeping_overridden); static cpumask_var_t housekeeping_mask; static unsigned int housekeeping_flags; +bool support_cpu0_nohz_full;
bool housekeeping_enabled(enum hk_flags flags) { @@ -96,18 +97,28 @@ static int __init housekeeping_setup(char *str, enum hk_flags flags) alloc_bootmem_cpumask_var(&housekeeping_mask); cpumask_andnot(housekeeping_mask, cpu_possible_mask, non_housekeeping_mask); + if (support_cpu0_nohz_full && cpumask_empty(housekeeping_mask)) { + pr_warn("Housekeeping cpumask is NULL, using boot CPU\n"); + __cpumask_set_cpu(smp_processor_id(), housekeeping_mask); + /* update non_housekeeping_mask because it will be used below + in tick_nohz_full_setup() */ + cpumask_andnot(non_housekeeping_mask, + cpu_possible_mask, housekeeping_mask); + }
cpumask_andnot(tmp, cpu_present_mask, non_housekeeping_mask); - if (cpumask_empty(tmp)) { + if (!support_cpu0_nohz_full && cpumask_empty(tmp)) { pr_warn("Housekeeping: must include one present CPU, " "using boot CPU:%d\n", smp_processor_id()); __cpumask_set_cpu(smp_processor_id(), housekeeping_mask); __cpumask_clear_cpu(smp_processor_id(), non_housekeeping_mask); } } else { - cpumask_andnot(tmp, cpu_present_mask, non_housekeeping_mask); - if (cpumask_empty(tmp)) - __cpumask_clear_cpu(smp_processor_id(), non_housekeeping_mask); + if (!support_cpu0_nohz_full) { + cpumask_andnot(tmp, cpu_present_mask, non_housekeeping_mask); + if (cpumask_empty(tmp)) + __cpumask_clear_cpu(smp_processor_id(), non_housekeeping_mask); + } cpumask_andnot(tmp, cpu_possible_mask, non_housekeeping_mask); if (!cpumask_equal(tmp, housekeeping_mask)) { pr_warn("Housekeeping: nohz_full= must match isolcpus=\n"); @@ -206,3 +217,10 @@ static int __init enhanced_isolcpus_setup(char *str) return 0; } __setup("enhanced_isolcpus", enhanced_isolcpus_setup); + +static int __init support_cpu0_nohz_full_setup(char *str) +{ + support_cpu0_nohz_full = true; + return 0; +} +early_param("support_cpu0_nohz_full", support_cpu0_nohz_full_setup);