diff options
| -rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
| -rw-r--r-- | kernel/smp.c | 35 |
2 files changed, 38 insertions, 1 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 742f69d18fc8..6834ace0c778 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -548,6 +548,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. embedded devices based on command line input. See Documentation/block/cmdline-partition.txt + boot_cpus= [SMP] + Rather than attempting to online all possible CPUs at + boot time, only online the specified set of CPUs. + boot_delay= Milliseconds to delay each printk during boot. Values larger than 10 seconds (10000) are changed to no delay (0). diff --git a/kernel/smp.c b/kernel/smp.c index d903c02223af..abdc48cd79a3 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -32,6 +32,9 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(struct call_function_data, cfd_data); static DEFINE_PER_CPU_SHARED_ALIGNED(struct llist_head, call_single_queue); static void flush_smp_call_function_queue(bool warn_cpu_offline); +/* CPU mask indicating which CPUs to bring online during smp_init() */ +static bool have_boot_cpu_mask; +static cpumask_var_t boot_cpu_mask; static int hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu) @@ -548,6 +551,19 @@ static int __init maxcpus(char *str) early_param("maxcpus", maxcpus); +static int __init boot_cpus(char *str) +{ + alloc_bootmem_cpumask_var(&boot_cpu_mask); + if (cpulist_parse(str, boot_cpu_mask) < 0) { + pr_warn("SMP: Incorrect boot_cpus cpumask\n"); + return -EINVAL; + } + have_boot_cpu_mask = true; + return 0; +} + +early_param("boot_cpus", boot_cpus); + /* Setup number of possible processor ids */ int nr_cpu_ids __read_mostly = NR_CPUS; EXPORT_SYMBOL(nr_cpu_ids); @@ -563,6 +579,21 @@ void __weak smp_announce(void) printk(KERN_INFO "Brought up %d CPUs\n", num_online_cpus()); } +/* Should the given CPU be booted during smp_init() ? */ +static inline bool boot_cpu(int cpu) +{ + if (!have_boot_cpu_mask) + return true; + + return cpumask_test_cpu(cpu, boot_cpu_mask); +} + +static inline void free_boot_cpu_mask(void) +{ + if (have_boot_cpu_mask) /* Allocated from boot_cpus() */ + free_bootmem_cpumask_var(boot_cpu_mask); +} + /* Called by boot processor to activate the rest. */ void __init smp_init(void) { @@ -574,10 +605,12 @@ void __init smp_init(void) for_each_present_cpu(cpu) { if (num_online_cpus() >= setup_max_cpus) break; - if (!cpu_online(cpu)) + if (!cpu_online(cpu) && boot_cpu(cpu)) cpu_up(cpu); } + free_boot_cpu_mask(); + /* Any cleanup work */ smp_announce(); smp_cpus_done(setup_max_cpus); |
