Skip to contentSkip to conversation

CONFIG_NR_CPUS

PATCH In review Andrew Morton 8 participants 12 messages Jun 6, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 CONFIG_NR_CPUS

Reducing NR_CPUS from 32 to 2 reduces the kernel footprint by approximately 240 kilobytes.

Before:
text data bss dec hex filename
2120633 283268 251572 2655473 2884f1 vmlinux

After:
text data bss dec hex filename
2120777 390116 384308 2895201 2c2d61 vmlinux

arch/i386/config.in renamed from arch/i386/config.in~config_nr_cpus +2 -1
@@ -185,8 +185,8 @@ fi
 
 bool 'Math emulation' CONFIG_MATH_EMULATION
 bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
-bool 'Symmetric multi-processing support' CONFIG_SMP
 bool 'Preemptible Kernel' CONFIG_PREEMPT
+bool 'Symmetric multi-processing support' CONFIG_SMP
 if [ "$CONFIG_SMP" != "y" ]; then
    bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC
    dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC
@@ -197,6 +197,7 @@ if [ "$CONFIG_SMP" != "y" ]; then
       define_bool CONFIG_X86_IO_APIC y
    fi
 else
+   int  'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32
    bool 'Multiquad NUMA system' CONFIG_MULTIQUAD
 fi
 
include/linux/threads.h renamed from include/linux/threads.h~config_nr_cpus +6 -0
@@ -9,7 +9,13 @@
  */
  
 #ifdef CONFIG_SMP
+
+#ifdef CONFIG_NR_CPUS
+#define NR_CPUS CONFIG_NR_CPUS
+#else
 #define NR_CPUS	32		/* Max processors that can be running in SMP */
+#endif
+
 #else
 #define NR_CPUS 1
 #endif
arch/i386/Config.help renamed from arch/i386/Config.help~config_nr_cpus +8 -0
@@ -25,6 +25,14 @@ CONFIG_SMP
 
   If you don't know what to do here, say N.
 
+CONFIG_NR_CPUS
+  This allows you to specify the maximum number of CPUs which this
+  kernel will support.  The maximum supported value is 32 and the
+  mimimum value which makes sense is 2.
+
+  This is purely to save memory - each supported CPU adds
+  approximately eight kilobytes to the kernel image.
+
 CONFIG_PREEMPT
   This option reduces the latency of the kernel when reacting to
   real-time or interactive events by allowing a low priority process to
arch/i386/kernel/smpboot.c renamed from arch/i386/kernel/smpboot.c~config_nr_cpus +2 -2
@@ -54,7 +54,7 @@
 static int smp_b_stepping;
 
 /* Setup configured maximum number of CPUs to activate */
-static int max_cpus = -1;
+static int max_cpus = NR_CPUS;
 
 /* Total count of live CPUs */
 int smp_num_cpus = 1;
@@ -1145,7 +1145,7 @@ void __init smp_boot_cpus(void)
 
 		if (!(phys_cpu_present_map & (1 << bit)))
 			continue;
-		if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
+		if (max_cpus <= cpucount+1)
 			continue;
 
 		do_boot_cpu(apicid);

-

#1 lore raw

From: Andrew Morton <[email protected]>
Date: Thu, 06 Jun 2002 03:10:12 -0700

Reducing NR_CPUS from 32 to 2 reduces the kernel footprint by approximately 240 kilobytes.

Nice. While you're at it can you fix the value on 64-bit platforms when CONFIG_NR_CPUS is not specified? (it should be 64, not 32)

#2 lore raw
Quoted 3 lines · David S. Miller

Nice. While you're at it can you fix the value on 64-bit platforms when CONFIG_NR_CPUS is not specified? (it should be 64, not 32)

I agree, this is good. I often am toying with some debugging aid that is an array of NR_CPUS and waste a lot of memory with NR_CPUS stuck at 32... no reason my kernels should not be set to 2 or whatever I need.

I have attached a patch that is Andrew's + your request, Dave. Since what really determines the maximum number of CPUs is the size of unsigned long, I used that. Cool?

Robert Love

arch/i386/Config.help +8 -0
diff -urN linux-2.5.20/arch/i386/Config.help linux/arch/i386/Config.help
@@ -25,6 +25,14 @@
 
   If you don't know what to do here, say N.
 
+CONFIG_NR_CPUS
+  This allows you to specify the maximum number of CPUs which this
+  kernel will support.  The maximum supported value is 32 and the
+  mimimum value which makes sense is 2.
+
+  This is purely to save memory - each supported CPU adds
+  approximately eight kilobytes to the kernel image.
+
 CONFIG_PREEMPT
   This option reduces the latency of the kernel when reacting to
   real-time or interactive events by allowing a low priority process to
arch/i386/config.in +2 -1
diff -urN linux-2.5.20/arch/i386/config.in linux/arch/i386/config.in
@@ -185,8 +185,8 @@
 
 bool 'Math emulation' CONFIG_MATH_EMULATION
 bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
-bool 'Symmetric multi-processing support' CONFIG_SMP
 bool 'Preemptible Kernel' CONFIG_PREEMPT
+bool 'Symmetric multi-processing support' CONFIG_SMP
 if [ "$CONFIG_SMP" != "y" ]; then
    bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC
    dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC
@@ -197,6 +197,7 @@
       define_bool CONFIG_X86_IO_APIC y
    fi
 else
+   int  'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32
    bool 'Multiquad NUMA system' CONFIG_MULTIQUAD
 fi
 
arch/i386/kernel/smpboot.c +2 -2
diff -urN linux-2.5.20/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c
@@ -54,7 +54,7 @@
 static int smp_b_stepping;
 
 /* Setup configured maximum number of CPUs to activate */
-static int max_cpus = -1;
+static int max_cpus = NR_CPUS;
 
 /* Total count of live CPUs */
 int smp_num_cpus = 1;
@@ -1145,7 +1145,7 @@
 
 		if (!(phys_cpu_present_map & (1 << bit)))
 			continue;
-		if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
+		if (max_cpus <= cpucount+1)
 			continue;
 
 		do_boot_cpu(apicid);
include/linux/threads.h +10 -3
diff -urN linux-2.5.20/include/linux/threads.h linux/include/linux/threads.h
@@ -7,11 +7,18 @@
  * The default limit for the nr of threads is now in
  * /proc/sys/kernel/threads-max.
  */
- 
+
+/* Max processors that can be running in SMP */
 #ifdef CONFIG_SMP
-#define NR_CPUS	32		/* Max processors that can be running in SMP */
+
+#ifdef CONFIG_NR_CPUS
+#define NR_CPUS	CONFIG_NR_CPUS
+#else
+#define NR_CPUS	(sizeof(unsigned long) * 8)
+#endif
+
 #else
-#define NR_CPUS 1
+#define NR_CPUS	1
 #endif
 
 #define MIN_THREADS_LEFT_FOR_ROOT 4
#3 lore raw
In reply to David S. Miller
Quoted 11 lines · Robert Love
Quoted 3 lines · David S. Miller

Nice. While you're at it can you fix the value on 64-bit platforms when CONFIG_NR_CPUS is not specified? (it should be 64, not 32)

I agree, this is good. I often am toying with some debugging aid that is an array of NR_CPUS and waste a lot of memory with NR_CPUS stuck at 32... no reason my kernels should not be set to 2 or whatever I need.

Quoted 6 lines

I have attached a patch that is Andrew's + your request, Dave. Since what really determines the maximum number of CPUs is the size of unsigned long, I used that. Cool?

...
+#define NR_CPUS (sizeof(unsigned long) * 8)

OK. What I'll do is:

#ifdef CONFIG_SMP
#define NR_CPUS CONFIG_NR_CPUS
#else
#define NR_CPUS 1
#endif

and then go edit every SMP-capable arch's config.in/Config.help files. But the arch maintainers should test one case please - x86 was locking up at boot on quad CPU with NR_CPUS=2. Others may do the same.

About a quarter of the bloat is runqueues. If we could dynamically allocate those in sched_init() it would be good, because presumably vendor kernels will be configured for the maximum number of CPUs.

-

#4 lore raw

--snip/snip

Quoted 8 lines

OK. What I'll do is:

#ifdef CONFIG_SMP
#define NR_CPUS CONFIG_NR_CPUS
#else
#define NR_CPUS 1
#endif

Quoted 4 lines

and then go edit every SMP-capable arch's config.in/Config.help files. But the arch maintainers should test one case please - x86 was locking up at boot on quad CPU with NR_CPUS=2. Others may do the same.

well, what you need to do is make sure smp_num_cpu <= NR_CPUS, otherwise the kernel will go ballistic on several places within the code.

- at least in the network system there is the assumption, that NR_CPUS is the upper limit of cpus. after initialization, everything uses smp_num_cpus, which is a nice thing for cpu-hotplugging :)

tm

Signature · 1 line
in some way i do, and in some way i don't.
#5 lore raw
In reply to Andrew Morton
Quoted 8 lines · Thomas 'Dent' Mirlacher
Quoted 4 lines

and then go edit every SMP-capable arch's config.in/Config.help files. But the arch maintainers should test one case please - x86 was locking up at boot on quad CPU with NR_CPUS=2. Others may do the same.

well, what you need to do is make sure smp_num_cpu <= NR_CPUS, otherwise the kernel will go ballistic on several places within the code.

*nod*, relying on the user to get it right may not be as simple as it seems. Quite a few people were pleasantly surprised when their 2-way P4 Xeon become a 4-way HT P4 box.

Dave

Signature · 2 lines
| Dave Jones.        http://www.codemonkey.org.uk
| SuSE Labs
#6 lore raw
Quoted 6 lines · Dave Jones
Quoted 5 lines · Thomas 'Dent' Mirlacher
Quoted 4 lines

and then go edit every SMP-capable arch's config.in/Config.help files. But the arch maintainers should test one case please - x86 was locking up at boot on quad CPU with NR_CPUS=2. Others may do the same.

Quoted 7 lines
Quoted 3 lines

well, what you need to do is make sure smp_num_cpu <= NR_CPUS, otherwise the kernel will go ballistic on several places within the code.

*nod*, relying on the user to get it right may not be as simple as it seems. Quite a few people were pleasantly surprised when their 2-way P4 Xeon become a 4-way HT P4 box.

:)

you could allocate all the cpu-nr dependend structures during startup, but then you're limited to the nr of cpus present at startup time (and use smp_num_cpus instead of NR_CPUS)

- which means:

1) no recompilation when you upgrade your (already smp) box
2) no chance for cpu hotplugging

or the other choice, as it seems to be vafoured right now:

let the user pick, and blame the user if he/she did something wrong.

and a question: is current_thread_info()->cpu a logical cpu#, or
a harwired one.

if it's a logical one, the easiest solution for not crashing the kernel (on bootup - not talking about adding a cpu during runtime), would be to restrict mac_cpus to NR_CPUS.
if it's a harwired one, well, the user has to live with the consequences of a compilation time error.

just my $0.02

tm

Signature · 1 line
in some way i do, and in some way i don't.
#7 lore raw
In reply to David S. Miller
Quoted 3 lines · Andrew Morton

But the arch maintainers should test one case please - x86 was locking up at boot on quad CPU with NR_CPUS=2. Others may do the same.

Just a guess, but this could be because the two CPUs chosen for the boot sequence are not physically numbered 0 and 1, so they are overwriting the bounds of the per-CPU arrays.

Cheers, Andreas
--
Andreas Dilger
http://www-mddsp.enel.ucalgary.ca/People/adilger/
http://sourceforge.net/projects/ext2resize/

#8 lore raw
In reply to David S. Miller
Quoted 9 lines · Andreas Dilger
Quoted 3 lines · Andrew Morton

But the arch maintainers should test one case please - x86 was locking up at boot on quad CPU with NR_CPUS=2. Others may do the same.

Just a guess, but this could be because the two CPUs chosen for the boot sequence are not physically numbered 0 and 1, so they are overwriting the bounds of the per-CPU arrays.

Well the code was assuming that the number of physical CPUs was always <= NR_CPUS unless max_cpus had been specified. I fixed that in the patch.

-

#9 lore raw
In reply to Andrew Morton
Quoted 6 lines · Robert Love
Quoted 3 lines · David S. Miller

Nice. While you're at it can you fix the value on 64-bit platforms when CONFIG_NR_CPUS is not specified? (it should be 64, not 32)

Quoted 7 lines

I agree, this is good. I often am toying with some debugging aid that is an array of NR_CPUS and waste a lot of memory with NR_CPUS stuck at 32... no reason my kernels should not be set to 2 or whatever I need.

I have attached a patch that is Andrew's + your request, Dave. Since what really determines the maximum number of CPUs is the size of unsigned long, I used that. Cool?

Here's a (compile) tested version for PPC. arch/ppc/kernel/smp.c makes much less use of max_cpus, so this should be all that's needed. BTW, on x86 max_cpus could become __initdata if someone cares..

Signature · 33 lines
Tom Rini (TR1265)
http://gate.crashing.org/~trini/


===== arch/ppc/config.in 1.36 vs edited =====
--- 1.36/arch/ppc/config.in	Fri May 24 04:15:43 2002
+++ edited/arch/ppc/config.in	Thu Jun  6 09:30:39 2002
@@ -172,6 +172,7 @@
 bool 'Symmetric multi-processing support' CONFIG_SMP
 if [ "$CONFIG_SMP" = "y" ]; then
    bool '  Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS
+   int  '  Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32
 fi
 if [ "$CONFIG_SMP" != "y" ]; then
    bool 'Preemptible Kernel' CONFIG_PREEMPT
===== arch/ppc/Config.help 1.10 vs edited =====
--- 1.10/arch/ppc/Config.help	Fri May 24 03:38:05 2002
+++ edited/arch/ppc/Config.help	Thu Jun  6 09:31:04 2002
@@ -14,6 +14,14 @@
 
   If you don't know what to do here, say N.
 
+CONFIG_NR_CPUS
+  This allows you to specify the maximum number of CPUs which this
+  kernel will support.  The maximum supported value is 32 and the
+  mimimum value which makes sense is 2.
+
+  This is purely to save memory - each supported CPU adds
+  approximately eight kilobytes to the kernel image.
+
 CONFIG_PREEMPT
   This option reduces the latency of the kernel when reacting to
   real-time or interactive events by allowing a low priority process to
#10 lore raw
In reply to Andrew Morton
Quoted 10 lines · Robert Love

I have attached a patch that is Andrew's + your request, Dave. Since what really determines the maximum number of CPUs is the size of unsigned long, I used that. Cool?

Robert Love

diff -urN linux-2.5.20/arch/i386/Config.help linux/arch/i386/Config.help

arch/i386/Config.help line 30

Quoted 6 lines
arch/i386/Config.help +3 -0
@@ -25,6 +25,14 @@
 
   If you don't know what to do here, say N.
 
+CONFIG_NR_CPUS
+  This allows you to specify the maximum number of CPUs which this
+  kernel will support.  The maximum supported value is 32 and the
                                                          ^^

This isn't quite true now...

--Adam

#11 lore raw
Quoted 1 line · Adam Kropelin

This isn't quite true now...

Ah, but it is on i386 which is what that configure entry is... since this is in architecture-specific configure options, each arch must maintain its only Config.help and Configure.in code.

Arches with 64-bit longs can s/32/64/ there..

Robert Love