[patch 4/5] Patch to limit present cpus to fake cpu hot-add testing.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[NOTE: Not for mainline inclusion.. only necessary for testing purposes]

Patch to limit cpu_present_map to less that what is physically present.
This is used to test physical CPU hotplug by hiding entries being created
and emulate a hot-add of the CPU.

enable CONFIG_LIMIT_CPUS, and use cmdline option limit_cpus=X, where X
indicates number of CPUs to mark present when booted.

for e.g with limit_cpus=2 on a 4 way system, you will only notice 2 cpus
in /sys/devices/system/cpu/.

Signed-off-by: Ashok Raj <[email protected]>
-------------------------------------------------------------
 arch/i386/kernel/acpi/boot.c |    9 ++++++++-
 arch/x86_64/Kconfig          |    9 +++++++++
 arch/x86_64/kernel/mpparse.c |    2 +-
 arch/x86_64/kernel/smpboot.c |   26 ++++++++++++++++++++++++++
 init/main.c                  |   22 ++++++++++++++++++++++
 5 files changed, 66 insertions(+), 2 deletions(-)

Index: linux-2.6.16-rc4-mm1/arch/i386/kernel/acpi/boot.c
===================================================================
--- linux-2.6.16-rc4-mm1.orig/arch/i386/kernel/acpi/boot.c
+++ linux-2.6.16-rc4-mm1/arch/i386/kernel/acpi/boot.c
@@ -540,6 +540,12 @@ int acpi_map_lsapic(acpi_handle handle, 
 	buffer.length = ACPI_ALLOCATE_BUFFER;
 	buffer.pointer = NULL;
 
+#ifdef CONFIG_LIMIT_CPUS
+	cpus_complement(tmp_map, cpu_present_map);
+	cpu = first_cpu(tmp_map);
+	physid = bios_cpu_apicid[cpu];
+	printk ("Limit-cpus... activating CPU %d APIC_ID = %d\n", cpu, physid);
+#endif
 	tmp_map = cpu_present_map;
 	mp_register_lapic(physid, lapic->flags.enabled);
 
@@ -563,8 +569,8 @@ EXPORT_SYMBOL(acpi_map_lsapic);
 
 int acpi_unmap_lsapic(int cpu)
 {
+#ifndef CONFIG_LIMIT_CPUS
 	int i;
-
 	for_each_cpu(i) {
 		if (x86_acpiid_to_apicid[i] == x86_cpu_to_apicid[cpu]) {
 			x86_acpiid_to_apicid[i] = -1;
@@ -572,6 +578,7 @@ int acpi_unmap_lsapic(int cpu)
 		}
 	}
 	x86_cpu_to_apicid[cpu] = -1;
+#endif
 	cpu_clear(cpu, cpu_present_map);
 	num_processors--;
 
Index: linux-2.6.16-rc4-mm1/arch/x86_64/Kconfig
===================================================================
--- linux-2.6.16-rc4-mm1.orig/arch/x86_64/Kconfig
+++ linux-2.6.16-rc4-mm1/arch/x86_64/Kconfig
@@ -360,6 +360,15 @@ config HOTPLUG_CPU
 		Say N if you want to disable CPU hotplug.
 
 
+config LIMIT_CPUS
+   bool "Limits the present CPUs  at boot time"
+   depends on HOTPLUG_CPU
+   default n
+   ---help---
+   At boot time pass command line option "limit_cpus=xx" to start with
+   xx number of cpus. The cpu_present_map is trimmed to hide these CPUs
+   so they can be made to appear hotplugged for testing purposes.
+
 config HPET_TIMER
 	bool
 	default y
Index: linux-2.6.16-rc4-mm1/arch/x86_64/kernel/mpparse.c
===================================================================
--- linux-2.6.16-rc4-mm1.orig/arch/x86_64/kernel/mpparse.c
+++ linux-2.6.16-rc4-mm1/arch/x86_64/kernel/mpparse.c
@@ -65,7 +65,7 @@ unsigned long mp_lapic_addr = 0;
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_id = -1U;
 /* Internal processor count */
-unsigned int num_processors __initdata = 0;
+unsigned int num_processors __cpuinitdata = 0;
 
 unsigned disabled_cpus __initdata;
 
Index: linux-2.6.16-rc4-mm1/arch/x86_64/kernel/smpboot.c
===================================================================
--- linux-2.6.16-rc4-mm1.orig/arch/x86_64/kernel/smpboot.c
+++ linux-2.6.16-rc4-mm1/arch/x86_64/kernel/smpboot.c
@@ -1006,6 +1006,32 @@ __init void prefill_possible_map(void)
 	for (i = 0; i < possible; i++)
 		cpu_set(i, cpu_possible_map);
 }
+
+#ifdef CONFIG_LIMIT_CPUS
+void __init limit_cpu_present_map(void)
+{
+   extern unsigned int limit_cpus;
+   char str[NR_CPUS];
+   unsigned int cnt;
+
+   if (num_processors <= limit_cpus)
+       return;
+
+   printk (KERN_INFO "cpu_present_map = %s\n",\
+       cpumask_scnprintf(str, NR_CPUS, cpu_present_map)? str : NULL);
+
+   printk (KERN_INFO "Limiting to %d CPUs\n", limit_cpus);
+
+   for (cnt=limit_cpus; (cnt < num_processors); cnt++)
+   {
+       cpu_clear(cnt, cpu_present_map);
+   }
+   printk(KERN_INFO "cpu_present_map = %s\n",
+       cpumask_scnprintf(str, NR_CPUS, cpu_present_map)? str : NULL);
+
+}
+#endif
+
 #endif
 
 /*
Index: linux-2.6.16-rc4-mm1/init/main.c
===================================================================
--- linux-2.6.16-rc4-mm1.orig/init/main.c
+++ linux-2.6.16-rc4-mm1/init/main.c
@@ -151,6 +151,23 @@ static int __init maxcpus(char *str)
 
 __setup("maxcpus=", maxcpus);
 
+#ifdef CONFIG_LIMIT_CPUS
+unsigned int limit_cpus=NR_CPUS;
+
+static int __init
+set_limit_cpus(char *str)
+{
+   int ncpus;
+   get_option (&str, &ncpus);
+   limit_cpus = ncpus;
+   printk (KERN_INFO "Limiting cpus present count to %d\n", ncpus);
+   return 1;
+}
+
+__setup("limit_cpus=", set_limit_cpus);
+#endif
+
+
 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
 static const char *panic_later, *panic_param;
@@ -357,6 +374,11 @@ static void __init smp_init(void)
 {
 	unsigned int i;
 
+#ifdef CONFIG_LIMIT_CPUS
+   extern __init void limit_cpu_present_map(void);
+   limit_cpu_present_map();
+#endif
+
 	/* FIXME: This should be done in userspace --RR */
 	for_each_present_cpu(i) {
 		if (num_online_cpus() >= max_cpus)

--

-
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/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux