Skip to contentSkip to conversation

x86 boot: Wait for boot cpu to show up if nr_cpus limit is about to hit

PATCH In review Vivek Goyal 2 participants 3 messages Jul 8, 2011 – Jul 9, 2011 x86

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 x86 boot: Wait for boot cpu to show up if nr_cpus limit is about to hit

nr_cpus allows one to specify number of possible cpus in the system. Current assumption seems to be that first cpu to show up is boot cpu and this assumption will be broken in kdump scenario where we can be booting on a non boot cpu with nr_cpus=1.

It might happen that first cpu we parse is not the cpu we boot on and later we ignore boot cpu. Though code later seems to recognize this anomaly and forcibly sets boot cpu in physical cpu map with following warning.

if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) {
        printk(KERN_WARNING
                "weird, boot CPU (#%d) not listed by the BIOS.\n",
                hard_smp_processor_id());

        physid_set(hard_smp_processor_id(), phys_cpu_present_map);
}

This patch waits for boot cpu to show up and starts ignoring the cpus once we have hit (nr_cpus - 1) number of cpus. So effectively we are reserving one slot out of nr_cpus for boot cpu explicitly.

---
 arch/x86/kernel/apic/apic.c |   22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)
arch/x86/kernel/apic/apic.c +20 -2
Index: linux-2.6/arch/x86/kernel/apic/apic.c
===================================================================
@@ -1943,10 +1943,28 @@ void disconnect_bsp_APIC(int virt_wire_s
 
 void __cpuinit generic_processor_info(int apicid, int version)
 {
-	int cpu;
+	int cpu, max = nr_cpu_ids;
+	bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid,
+				phys_cpu_present_map);
+
+	/*
+	 * If boot cpu has not been detected yet, then only allow upto
+	 * nr_cpu_ids - 1 processors and keep one slot free for boot cpu
+	 */
+	if (!boot_cpu_detected && num_processors >= nr_cpu_ids - 1 &&
+	    apicid != boot_cpu_physical_apicid) {
+		int thiscpu = max + disabled_cpus - 1;
+
+		pr_warning(
+			"ACPI: NR_CPUS/possible_cpus limit of %i almost"
+			" reached. Keeping one slot for boot cpu."
+			"  Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
+
+		disabled_cpus++;
+		return;
+	}
 
 	if (num_processors >= nr_cpu_ids) {
-		int max = nr_cpu_ids;
 		int thiscpu = max + disabled_cpus;
 
 		pr_warning(
Acked-by on v1 1/1
#1 lore raw
Quoted 15 lines · Vivek Goyal

nr_cpus allows one to specify number of possible cpus in the system. Current assumption seems to be that first cpu to show up is boot cpu and this assumption will be broken in kdump scenario where we can be booting on a non boot cpu with nr_cpus=1.

It might happen that first cpu we parse is not the cpu we boot on and later we ignore boot cpu. Though code later seems to recognize this anomaly and forcibly sets boot cpu in physical cpu map with following warning.

if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { printk(KERN_WARNING
               "weird, boot CPU (#%d) not listed by the BIOS.\n", hard_smp_processor_id());

Quoted 8 lines

       physid_set(hard_smp_processor_id(), phys_cpu_present_map); }

This patch waits for boot cpu to show up and starts ignoring the cpus once we have hit (nr_cpus - 1) number of cpus. So effectively we are reserving one slot out of nr_cpus for boot cpu explicitly.

Quoted 45 lines

---
 arch/x86/kernel/apic/apic.c |   22 ++++++++++++++++++++--

 1 file changed, 20 insertions(+), 2 deletions(-)

Index: linux-2.6/arch/x86/kernel/apic/apic.c
===================================================================

arch/x86/kernel/apic/apic.c       2011-07-08 12:02:01.272223921 -0400 renamed from arch/x86/kernel/apic/apic.c  2011-07-08 10:44:48.003709709 -0400 +20 -2
@@ -1943,10 +1943,28 @@ void disconnect_bsp_APIC(int virt_wire_s
 
  void __cpuinit generic_processor_info(int apicid, int version)
  {
-       int cpu;
+       int cpu, max = nr_cpu_ids;
+       bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid,
+                               phys_cpu_present_map);
+
+       /*
+        * If boot cpu has not been detected yet, then only allow upto
+        * nr_cpu_ids - 1 processors and keep one slot free for boot cpu
+        */
+       if (!boot_cpu_detected && num_processors >= nr_cpu_ids - 1 &&
+           apicid != boot_cpu_physical_apicid) {
+               int thiscpu = max + disabled_cpus - 1;
+
+               pr_warning(
+                       "ACPI: NR_CPUS/possible_cpus limit of %i almost"
+                       " reached. Keeping one slot for boot cpu."
+                       "  Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
+
+               disabled_cpus++;
+               return;
+       }
 
        if (num_processors >= nr_cpu_ids) {
-               int max = nr_cpu_ids;
                int thiscpu = max + disabled_cpus;
 

               pr_warning(
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

#2 lore raw

[tip:x86/smpboot] x86, boot: Wait for boot cpu to show up if nr_cpus limit is about to hit

In reply to Vivek Goyal
Commit-ID:  14cb6dcf0a023f5977461c94d8d5a163c937979b
Gitweb:     http://git.kernel.org/tip/14cb6dcf0a023f5977461c94d8d5a163c937979b
Author:     Vivek Goyal <[email protected]>
AuthorDate: Fri, 8 Jul 2011 13:19:26 -0400
Committer:  H. Peter Anvin <[email protected]>
CommitDate: Fri, 8 Jul 2011 15:33:35 -0700

x86, boot: Wait for boot cpu to show up if nr_cpus limit is about to hit

nr_cpus allows one to specify number of possible cpus in the system. Current assumption seems to be that first cpu to show up is boot cpu and this assumption will be broken in kdump scenario where we can be booting on a non boot cpu with nr_cpus=1.

It might happen that first cpu we parse is not the cpu we boot on and later we ignore boot cpu. Though code later seems to recognize this anomaly and forcibly sets boot cpu in physical cpu map with following warning.

if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) {
        printk(KERN_WARNING
                "weird, boot CPU (#%d) not listed by the BIOS.\n",
                hard_smp_processor_id());

        physid_set(hard_smp_processor_id(), phys_cpu_present_map);
}

This patch waits for boot cpu to show up and starts ignoring the cpus once we have hit (nr_cpus - 1) number of cpus. So effectively we are reserving one slot out of nr_cpus for boot cpu explicitly.

---
 arch/x86/kernel/apic/apic.c |   22 ++++++++++++++++++++--
 1 files changed, 20 insertions(+), 2 deletions(-)
arch/x86/kernel/apic/apic.c +20 -2
index b9338b8..68219a9 100644
@@ -1943,10 +1943,28 @@ void disconnect_bsp_APIC(int virt_wire_setup)
 
 void __cpuinit generic_processor_info(int apicid, int version)
 {
-	int cpu;
+	int cpu, max = nr_cpu_ids;
+	bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid,
+				phys_cpu_present_map);
+
+	/*
+	 * If boot cpu has not been detected yet, then only allow upto
+	 * nr_cpu_ids - 1 processors and keep one slot free for boot cpu
+	 */
+	if (!boot_cpu_detected && num_processors >= nr_cpu_ids - 1 &&
+	    apicid != boot_cpu_physical_apicid) {
+		int thiscpu = max + disabled_cpus - 1;
+
+		pr_warning(
+			"ACPI: NR_CPUS/possible_cpus limit of %i almost"
+			" reached. Keeping one slot for boot cpu."
+			"  Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
+
+		disabled_cpus++;
+		return;
+	}
 
 	if (num_processors >= nr_cpu_ids) {
-		int max = nr_cpu_ids;
 		int thiscpu = max + disabled_cpus;
 
 		pr_warning(