Commit d38265ed authored by Xiongfeng Wang's avatar Xiongfeng Wang
Browse files

isolation: Do not check whether housekeeping CPUs are present

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: default avatarXiongfeng Wang <wangxiongfeng2@huawei.com>
parent f300accf
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -41,8 +41,10 @@ extern void tick_irq_enter(void);
#  ifndef arch_needs_cpu
#   define arch_needs_cpu() (0)
#  endif
extern bool support_cpu0_nohz_full;
# else
static inline void tick_irq_enter(void) { }
#define support_cpu0_nohz_full 0
#endif

#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
+16 −4
Original line number Diff line number Diff line
@@ -96,18 +96,30 @@ 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 {
		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");
+9 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@
 */
static DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched);

bool support_cpu0_nohz_full;

struct tick_sched *tick_get_tick_sched(int cpu)
{
	return &per_cpu(tick_cpu_sched, cpu);
@@ -1559,3 +1561,10 @@ int tick_check_oneshot_change(int allow_nohz)
	tick_nohz_switch_to_nohz();
	return 0;
}

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);