How to add bootcpus feature on kernel5.10

In a heterogenous multiprocessor system, specifying the 'maxcpus'
parameter on kernel command line does not provide sufficient control
over which CPUs are brought online at kernel boot time, since CPUs may
have nonuniform performance characterstics. Thus, add bootcpus kernel
parameter to control which CPUs should be brought online during kernel
boot. When both maxcpus and bootcpus is set, the more restrictive of the
two are booted.

Change-Id: I1e514d23139a348db49d00c8bb2bf19461c5e2be
Signed-off-by: Elliot Berman <eberman@codeaurora.org>
---
 Documentation/admin-guide/kernel-parameters.txt |  8 +++++++
 include/linux/cpu.h                             |  2 +-
 kernel/cpu.c                                    |  4 ++--
 kernel/smp.c                                    | 28 +++++++++++++++++++++++--
 4 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 29c5f46..f811c24 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -469,6 +469,14 @@
 
 			See Documentation/admin-guide/bootconfig.rst
 
+	bootcpus=	[SMP]  List of processors that an SMP kernel
+			will bring up during bootup. Similar to maxcpus, except
+			as a cpu list as described above. The more restrictive
+			of maxcpus and bootcpus applies. If bootcpus=1-3 and
+			maxcpus=2, only processors 1 and 2 are booted. As with
+			maxcpus, you can bring up other plugged cpu by executing
+			"echo 1 > /sys/devices/system/cpu/cpuX/online"
+
 	bert_disable	[ACPI]
 			Disable BERT OS support on buggy BIOSes.
 
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 22ae91f8..7872b9c 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -95,7 +95,7 @@ void notify_cpu_starting(unsigned int cpu);
 extern void cpu_maps_update_begin(void);
 extern void cpu_maps_update_done(void);
 int bringup_hibernate_cpu(unsigned int sleep_cpu);
-void bringup_nonboot_cpus(unsigned int setup_max_cpus);
+void bringup_nonboot_cpus(unsigned int setup_max_cpus, cpumask_var_t boot_cpus);
 
 #else	/* CONFIG_SMP */
 #define cpuhp_tasks_frozen	0
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 49d2eea..ea9958a 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1596,14 +1596,14 @@ int bringup_hibernate_cpu(unsigned int sleep_cpu)
 	return 0;
 }
 
-void bringup_nonboot_cpus(unsigned int setup_max_cpus)
+void bringup_nonboot_cpus(unsigned int setup_max_cpus, cpumask_var_t boot_cpus)
 {
 	unsigned int cpu;
 
 	for_each_present_cpu(cpu) {
 		if (num_online_cpus() >= setup_max_cpus)
 			break;
-		if (!cpu_online(cpu))
+		if (!cpu_online(cpu) && cpumask_test_cpu(cpu, boot_cpus))
 			cpu_up(cpu, CPUHP_ONLINE);
 	}
 }
diff --git a/kernel/smp.c b/kernel/smp.c
index d703309..8baee0f 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -743,7 +743,7 @@ EXPORT_SYMBOL(smp_call_function);
 /* Setup configured maximum number of CPUs to activate */
 unsigned int setup_max_cpus = NR_CPUS;
 EXPORT_SYMBOL(setup_max_cpus);
-
+static cpumask_var_t boot_cpus;
 
 /*
  * Setup routine for controlling SMP activation
@@ -792,6 +792,27 @@ static int __init maxcpus(char *str)
 
 early_param("maxcpus", maxcpus);
 
+static int __init bootcpus(char *str)
+{
+	alloc_bootmem_cpumask_var(&boot_cpus);
+	if (cpulist_parse(str, boot_cpus) < 0) {
+		pr_warn("incorrect bootcpus mask\n");
+		return -EINVAL;
+	}
+	cpumask_set_cpu(smp_processor_id(), boot_cpus);
+	return 0;
+}
+
+early_param("bootcpus", bootcpus);
+
+static void __init boot_cpus_init(void)
+{
+	if (!cpumask_available(boot_cpus))
+		zalloc_cpumask_var(&boot_cpus, GFP_NOWAIT);
+	if (cpumask_empty(boot_cpus))
+		cpumask_setall(boot_cpus);
+}
+
 /* Setup number of possible processor ids */
 unsigned int nr_cpu_ids __read_mostly = NR_CPUS;
 EXPORT_SYMBOL(nr_cpu_ids);
@@ -809,10 +830,13 @@ void __init smp_init(void)
 
 	idle_threads_init();
 	cpuhp_threads_init();
+	boot_cpus_init();
 
 	pr_info("Bringing up secondary CPUs ...\n");
 
-	bringup_nonboot_cpus(setup_max_cpus);
+	bringup_nonboot_cpus(setup_max_cpus, boot_cpus);
+
+	free_bootmem_cpumask_var(boot_cpus);
 
 	num_nodes = num_online_nodes();
 	num_cpus  = num_online_cpus();
-- 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值