* [PATCH 01/10] x86_64: Cleanup non-smp usage of cpu maps v4
2008-03-25 2:19 [PATCH 00/10] NR_CPUS: third reduction of NR_CPUS memory usage Mike Travis
@ 2008-03-25 2:19 ` Mike Travis
2008-03-25 2:19 ` [PATCH 02/10] init: move setup of nr_cpu_ids to as early as possible v4 Mike Travis
` (8 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Mike Travis @ 2008-03-25 2:19 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, linux-kernel, Andi Kleen, Ingo Molnar, Thomas Gleixner,
Christoph Lameter
[-- Attachment #1: cleanup --]
[-- Type: text/plain, Size: 8010 bytes --]
Cleanup references to the early cpu maps for the non-SMP configuration
and remove some functions called for SMP configurations only.
Based on linux-2.6.25-rc5-mm1
Cc: Andi Kleen <ak@suse.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Mike Travis <travis@sgi.com>
---
This patch was moved from the zero-based percpu variables patchset to here.
---
arch/x86/kernel/genapic_64.c | 2 +
arch/x86/kernel/mpparse_64.c | 2 +
arch/x86/kernel/setup64.c | 45 ++++++++++++++++++++++---------------------
arch/x86/kernel/smpboot_32.c | 2 +
arch/x86/mm/numa_64.c | 4 ++-
include/asm-x86/smp_32.h | 4 +++
include/asm-x86/smp_64.h | 5 ++++
include/asm-x86/topology.h | 16 +++++++++++----
8 files changed, 54 insertions(+), 26 deletions(-)
--- linux-2.6.25-rc5.orig/arch/x86/kernel/genapic_64.c
+++ linux-2.6.25-rc5/arch/x86/kernel/genapic_64.c
@@ -25,9 +25,11 @@
#endif
/* which logical CPU number maps to which CPU (physical APIC ID) */
+#ifdef CONFIG_SMP
u16 x86_cpu_to_apicid_init[NR_CPUS] __initdata
= { [0 ... NR_CPUS-1] = BAD_APICID };
void *x86_cpu_to_apicid_early_ptr;
+#endif
DEFINE_PER_CPU(u16, x86_cpu_to_apicid) = BAD_APICID;
EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
--- linux-2.6.25-rc5.orig/arch/x86/kernel/mpparse_64.c
+++ linux-2.6.25-rc5/arch/x86/kernel/mpparse_64.c
@@ -67,9 +67,11 @@ unsigned disabled_cpus __cpuinitdata;
/* Bitmask of physically existing CPUs */
physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
+#ifdef CONFIG_SMP
u16 x86_bios_cpu_apicid_init[NR_CPUS] __initdata
= { [0 ... NR_CPUS-1] = BAD_APICID };
void *x86_bios_cpu_apicid_early_ptr;
+#endif
DEFINE_PER_CPU(u16, x86_bios_cpu_apicid) = BAD_APICID;
EXPORT_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
--- linux-2.6.25-rc5.orig/arch/x86/kernel/setup64.c
+++ linux-2.6.25-rc5/arch/x86/kernel/setup64.c
@@ -86,6 +86,8 @@ static int __init nonx32_setup(char *str
}
__setup("noexec32=", nonx32_setup);
+
+#ifdef CONFIG_SMP
/*
* Copy data used in early init routines from the initial arrays to the
* per cpu data areas. These arrays then become expendable and the
@@ -96,23 +98,13 @@ static void __init setup_per_cpu_maps(vo
int cpu;
for_each_possible_cpu(cpu) {
-#ifdef CONFIG_SMP
- if (per_cpu_offset(cpu)) {
-#endif
- per_cpu(x86_cpu_to_apicid, cpu) =
- x86_cpu_to_apicid_init[cpu];
- per_cpu(x86_bios_cpu_apicid, cpu) =
+ per_cpu(x86_cpu_to_apicid, cpu) = x86_cpu_to_apicid_init[cpu];
+ per_cpu(x86_bios_cpu_apicid, cpu) =
x86_bios_cpu_apicid_init[cpu];
#ifdef CONFIG_NUMA
- per_cpu(x86_cpu_to_node_map, cpu) =
+ per_cpu(x86_cpu_to_node_map, cpu) =
x86_cpu_to_node_map_init[cpu];
#endif
-#ifdef CONFIG_SMP
- }
- else
- printk(KERN_NOTICE "per_cpu_offset zero for cpu %d\n",
- cpu);
-#endif
}
/* indicate the early static arrays will soon be gone */
@@ -140,26 +132,37 @@ void __init setup_per_cpu_areas(void)
/* Copy section for each CPU (we discard the original) */
size = PERCPU_ENOUGH_ROOM;
- printk(KERN_INFO "PERCPU: Allocating %lu bytes of per cpu data\n", size);
- for_each_cpu_mask (i, cpu_possible_map) {
+ printk(KERN_INFO
+ "PERCPU: Allocating %lu bytes of per cpu data\n", size);
+
+ for_each_possible_cpu(i) {
+
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+ char *ptr = alloc_bootmem_pages(size);
+#else
char *ptr;
+ int node = early_cpu_to_node(i);
- if (!NODE_DATA(early_cpu_to_node(i))) {
- printk("cpu with no node %d, num_online_nodes %d\n",
- i, num_online_nodes());
+ if (NODE_DATA(node))
+ ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
+
+ else {
ptr = alloc_bootmem_pages(size);
- } else {
- ptr = alloc_bootmem_pages_node(NODE_DATA(early_cpu_to_node(i)), size);
+ printk(KERN_INFO
+ "cpu %d has no node or node-local memory\n", i);
}
+#endif
if (!ptr)
panic("Cannot allocate cpu data for CPU %d\n", i);
+
cpu_pda(i)->data_offset = ptr - __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
}
- /* setup percpu data maps early */
+ /* Setup percpu data maps */
setup_per_cpu_maps();
}
+#endif /* CONFIG_SMP */
void pda_init(int cpu)
{
--- linux-2.6.25-rc5.orig/arch/x86/kernel/smpboot_32.c
+++ linux-2.6.25-rc5/arch/x86/kernel/smpboot_32.c
@@ -92,9 +92,11 @@ DEFINE_PER_CPU_SHARED_ALIGNED(struct cpu
EXPORT_PER_CPU_SYMBOL(cpu_info);
/* which logical CPU number maps to which CPU (physical APIC ID) */
+#ifdef CONFIG_SMP
u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata =
{ [0 ... NR_CPUS-1] = BAD_APICID };
void *x86_cpu_to_apicid_early_ptr;
+#endif
DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
--- linux-2.6.25-rc5.orig/arch/x86/mm/numa_64.c
+++ linux-2.6.25-rc5/arch/x86/mm/numa_64.c
@@ -31,13 +31,15 @@ bootmem_data_t plat_node_bdata[MAX_NUMNO
struct memnode memnode;
+#ifdef CONFIG_SMP
int x86_cpu_to_node_map_init[NR_CPUS] = {
[0 ... NR_CPUS-1] = NUMA_NO_NODE
};
void *x86_cpu_to_node_map_early_ptr;
+EXPORT_SYMBOL(x86_cpu_to_node_map_early_ptr);
+#endif
DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE;
EXPORT_PER_CPU_SYMBOL(x86_cpu_to_node_map);
-EXPORT_SYMBOL(x86_cpu_to_node_map_early_ptr);
s16 apicid_to_node[MAX_LOCAL_APIC] __cpuinitdata = {
[0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
--- linux-2.6.25-rc5.orig/include/asm-x86/smp_32.h
+++ linux-2.6.25-rc5/include/asm-x86/smp_32.h
@@ -29,8 +29,12 @@ extern void unlock_ipi_call_lock(void);
extern void (*mtrr_hook) (void);
extern void zap_low_mappings (void);
+#ifdef CONFIG_SMP
extern u8 __initdata x86_cpu_to_apicid_init[];
extern void *x86_cpu_to_apicid_early_ptr;
+#else
+#define x86_cpu_to_apicid_early_ptr NULL
+#endif
DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
DECLARE_PER_CPU(cpumask_t, cpu_core_map);
--- linux-2.6.25-rc5.orig/include/asm-x86/smp_64.h
+++ linux-2.6.25-rc5/include/asm-x86/smp_64.h
@@ -26,10 +26,15 @@ extern void unlock_ipi_call_lock(void);
extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *),
void *info, int wait);
+#ifdef CONFIG_SMP
extern u16 __initdata x86_cpu_to_apicid_init[];
extern u16 __initdata x86_bios_cpu_apicid_init[];
extern void *x86_cpu_to_apicid_early_ptr;
extern void *x86_bios_cpu_apicid_early_ptr;
+#else
+#define x86_cpu_to_apicid_early_ptr NULL
+#define x86_bios_cpu_apicid_early_ptr NULL
+#endif
DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
DECLARE_PER_CPU(cpumask_t, cpu_core_map);
--- linux-2.6.25-rc5.orig/include/asm-x86/topology.h
+++ linux-2.6.25-rc5/include/asm-x86/topology.h
@@ -35,8 +35,14 @@ extern int cpu_to_node_map[];
#else
DECLARE_PER_CPU(int, x86_cpu_to_node_map);
+
+#ifdef CONFIG_SMP
extern int x86_cpu_to_node_map_init[];
extern void *x86_cpu_to_node_map_early_ptr;
+#else
+#define x86_cpu_to_node_map_early_ptr NULL
+#endif
+
/* Returns the number of the current Node. */
#define numa_node_id() (early_cpu_to_node(raw_smp_processor_id()))
#endif
@@ -54,6 +60,8 @@ static inline int cpu_to_node(int cpu)
}
#else /* CONFIG_X86_64 */
+
+#ifdef CONFIG_SMP
static inline int early_cpu_to_node(int cpu)
{
int *cpu_to_node_map = x86_cpu_to_node_map_early_ptr;
@@ -65,6 +73,9 @@ static inline int early_cpu_to_node(int
else
return NUMA_NO_NODE;
}
+#else
+#define early_cpu_to_node(cpu) cpu_to_node(cpu)
+#endif
static inline int cpu_to_node(int cpu)
{
@@ -76,10 +87,7 @@ static inline int cpu_to_node(int cpu)
return ((int *)x86_cpu_to_node_map_early_ptr)[cpu];
}
#endif
- if (per_cpu_offset(cpu))
- return per_cpu(x86_cpu_to_node_map, cpu);
- else
- return NUMA_NO_NODE;
+ return per_cpu(x86_cpu_to_node_map, cpu);
}
#endif /* CONFIG_X86_64 */
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 02/10] init: move setup of nr_cpu_ids to as early as possible v4
2008-03-25 2:19 [PATCH 00/10] NR_CPUS: third reduction of NR_CPUS memory usage Mike Travis
2008-03-25 2:19 ` [PATCH 01/10] x86_64: Cleanup non-smp usage of cpu maps v4 Mike Travis
@ 2008-03-25 2:19 ` Mike Travis
2008-03-25 2:19 ` [PATCH 03/10] cpufreq: change cpu freq arrays to per_cpu variables Mike Travis
` (7 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Mike Travis @ 2008-03-25 2:19 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, linux-kernel, Tony Luck, Paul Mackerras,
Anton Blanchard, David S. Miller, William L. Irwin,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin
[-- Attachment #1: setup-nr_cpu_ids --]
[-- Type: text/plain, Size: 5994 bytes --]
Move the setting of nr_cpu_ids from sched_init() to setup_per_cpu_areas(),
so that it's available as early as possible.
Based on linux-2.6.25-rc5-mm1
# ia64
Cc: Tony Luck <tony.luck@intel.com>
# powerpc
Cc: Paul Mackerras <paulus@samba.org>
Cc: Anton Blanchard <anton@samba.org>
# sparc
Cc: David S. Miller <davem@davemloft.net>
Cc: William L. Irwin <wli@holomorphy.com>
# x86
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Mike Travis <travis@sgi.com>
---
Moved from the zero-based percpu variables patchset and redone to be
integrated with setup_per_cpu_areas instead of being called before
that function. This had to be done because some arch's call
prefill_possible_map() from setup_per_cpu_areas() which may increase
the number of possible cpus.
---
arch/ia64/kernel/acpi.c | 4 ++++
arch/ia64/kernel/setup.c | 7 +++++++
arch/powerpc/kernel/setup_64.c | 5 ++++-
arch/sparc64/mm/init.c | 10 +++++++++-
arch/x86/kernel/setup64.c | 7 ++++++-
init/main.c | 15 ++++++++++++---
kernel/sched.c | 7 -------
7 files changed, 42 insertions(+), 13 deletions(-)
--- linux-2.6.25-rc5.orig/arch/ia64/kernel/acpi.c
+++ linux-2.6.25-rc5/arch/ia64/kernel/acpi.c
@@ -831,6 +831,10 @@ __init void prefill_possible_map(void)
for (i = 0; i < possible; i++)
cpu_set(i, cpu_possible_map);
+
+#ifdef CONFIG_SMP
+ nr_cpu_ids = possible;
+#endif
}
int acpi_map_lsapic(acpi_handle handle, int *pcpu)
--- linux-2.6.25-rc5.orig/arch/ia64/kernel/setup.c
+++ linux-2.6.25-rc5/arch/ia64/kernel/setup.c
@@ -766,6 +766,13 @@ setup_per_cpu_areas (void)
/* start_kernel() requires this... */
#ifdef CONFIG_ACPI_HOTPLUG_CPU
prefill_possible_map();
+#elif defined(CONFIG_SMP)
+ int cpu, highest_cpu = 0;
+
+ for_each_possible_cpu(cpu)
+ highest_cpu = cpu;
+
+ nr_cpu_ids = highest_cpu + 1;
#endif
}
--- linux-2.6.25-rc5.orig/arch/powerpc/kernel/setup_64.c
+++ linux-2.6.25-rc5/arch/powerpc/kernel/setup_64.c
@@ -576,7 +576,7 @@ void cpu_die(void)
#ifdef CONFIG_SMP
void __init setup_per_cpu_areas(void)
{
- int i;
+ int i, highest_cpu = 0;
unsigned long size;
char *ptr;
@@ -594,7 +594,10 @@ void __init setup_per_cpu_areas(void)
paca[i].data_offset = ptr - __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+ if (i > highest_cpu)
+ highest_cpu = i;
}
+ nr_cpu_ids = highest_cpu + 1;
/* Now that per_cpu is setup, initialize cpu_sibling_map */
smp_setup_cpu_sibling_map();
--- linux-2.6.25-rc5.orig/arch/sparc64/mm/init.c
+++ linux-2.6.25-rc5/arch/sparc64/mm/init.c
@@ -1292,10 +1292,18 @@ pgd_t swapper_pg_dir[2048];
static void sun4u_pgprot_init(void);
static void sun4v_pgprot_init(void);
-/* Dummy function */
+#ifdef CONFIG_SMP
+/* set nr_cpu_ids */
void __init setup_per_cpu_areas(void)
{
+ int cpu, highest_cpu = 0;
+
+ for_each_possible_cpu(cpu)
+ highest_cpu = cpu;
+
+ nr_cpu_ids = highest_cpu + 1;
}
+#endif
void __init paging_init(void)
{
--- linux-2.6.25-rc5.orig/arch/x86/kernel/setup64.c
+++ linux-2.6.25-rc5/arch/x86/kernel/setup64.c
@@ -122,7 +122,7 @@ static void __init setup_per_cpu_maps(vo
*/
void __init setup_per_cpu_areas(void)
{
- int i;
+ int i, highest_cpu = 0;
unsigned long size;
#ifdef CONFIG_HOTPLUG_CPU
@@ -157,7 +157,12 @@ void __init setup_per_cpu_areas(void)
cpu_pda(i)->data_offset = ptr - __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+
+ if (i > highest_cpu)
+ highest_cpu = i;
}
+ nr_cpu_ids = highest_cpu + 1;
+ printk(KERN_DEBUG "NR_CPUS: %d (nr_cpu_ids: %d)\n", NR_CPUS, nr_cpu_ids);
/* Setup percpu data maps */
setup_per_cpu_maps();
--- linux-2.6.25-rc5.orig/init/main.c
+++ linux-2.6.25-rc5/init/main.c
@@ -369,16 +369,20 @@ static inline void smp_prepare_cpus(unsi
#else
+int nr_cpu_ids __read_mostly = NR_CPUS;
+EXPORT_SYMBOL(nr_cpu_ids);
+
#ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
-
EXPORT_SYMBOL(__per_cpu_offset);
+/* nr_cpu_ids is set as a side effect */
static void __init setup_per_cpu_areas(void)
{
- unsigned long size, i;
- char *ptr;
+ unsigned long size;
+ int i, highest_cpu = 0;
unsigned long nr_possible_cpus = num_possible_cpus();
+ char *ptr;
/* Copy section for each CPU (we discard the original) */
size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
@@ -388,7 +392,12 @@ static void __init setup_per_cpu_areas(v
__per_cpu_offset[i] = ptr - __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
ptr += size;
+ if (i > highest_cpu)
+ highest_cpu = i;
}
+
+ nr_cpu_ids = highest_cpu + 1;
+ printk(KERN_DEBUG "NR_CPUS: %d (nr_cpu_ids: %d)\n", NR_CPUS, nr_cpu_ids);
}
#endif /* CONFIG_HAVE_SETUP_PER_CPU_AREA */
--- linux-2.6.25-rc5.orig/kernel/sched.c
+++ linux-2.6.25-rc5/kernel/sched.c
@@ -5995,10 +5995,6 @@ void __init migration_init(void)
#ifdef CONFIG_SMP
-/* Number of possible processor ids */
-int nr_cpu_ids __read_mostly = NR_CPUS;
-EXPORT_SYMBOL(nr_cpu_ids);
-
#ifdef CONFIG_SCHED_DEBUG
static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level)
@@ -7199,7 +7195,6 @@ static void init_tg_rt_entry(struct rq *
void __init sched_init(void)
{
- int highest_cpu = 0;
int i, j;
#ifdef CONFIG_SMP
@@ -7255,7 +7250,6 @@ void __init sched_init(void)
#endif
init_rq_hrtick(rq);
atomic_set(&rq->nr_iowait, 0);
- highest_cpu = i;
}
set_load_weight(&init_task);
@@ -7265,7 +7259,6 @@ void __init sched_init(void)
#endif
#ifdef CONFIG_SMP
- nr_cpu_ids = highest_cpu + 1;
open_softirq(SCHED_SOFTIRQ, run_rebalance_domains, NULL);
#endif
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 03/10] cpufreq: change cpu freq arrays to per_cpu variables
2008-03-25 2:19 [PATCH 00/10] NR_CPUS: third reduction of NR_CPUS memory usage Mike Travis
2008-03-25 2:19 ` [PATCH 01/10] x86_64: Cleanup non-smp usage of cpu maps v4 Mike Travis
2008-03-25 2:19 ` [PATCH 02/10] init: move setup of nr_cpu_ids to as early as possible v4 Mike Travis
@ 2008-03-25 2:19 ` Mike Travis
2008-03-25 2:19 ` [PATCH 04/10] acpi: change processors from array to per_cpu variable Mike Travis
` (6 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Mike Travis @ 2008-03-25 2:19 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-mm, linux-kernel, Dave Jones
[-- Attachment #1: nr_cpus-in-cpufreq-cpu_alloc --]
[-- Type: text/plain, Size: 11066 bytes --]
Change cpufreq_policy and cpufreq_governor pointer tables
from arrays to per_cpu variables in the cpufreq subsystem.
Also some minor complaints from checkpatch.pl fixed.
Based on linux-2.6.25-rc5-mm1
Cc: Dave Jones <davej@codemonkey.org.uk>
Signed-off-by: Mike Travis <travis@sgi.com>
---
drivers/cpufreq/cpufreq.c | 45 +++++++++++++++++++++-------------------
drivers/cpufreq/cpufreq_stats.c | 24 ++++++++++-----------
drivers/cpufreq/freq_table.c | 12 +++++-----
3 files changed, 42 insertions(+), 39 deletions(-)
--- linux-2.6.25-rc5.orig/drivers/cpufreq/cpufreq.c
+++ linux-2.6.25-rc5/drivers/cpufreq/cpufreq.c
@@ -38,10 +38,10 @@
* also protects the cpufreq_cpu_data array.
*/
static struct cpufreq_driver *cpufreq_driver;
-static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
+static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
#ifdef CONFIG_HOTPLUG_CPU
/* This one keeps track of the previously set governor of a removed CPU */
-static struct cpufreq_governor *cpufreq_cpu_governor[NR_CPUS];
+static DEFINE_PER_CPU(struct cpufreq_governor *, cpufreq_cpu_governor);
#endif
static DEFINE_SPINLOCK(cpufreq_driver_lock);
@@ -135,7 +135,7 @@ struct cpufreq_policy *cpufreq_cpu_get(u
struct cpufreq_policy *data;
unsigned long flags;
- if (cpu >= NR_CPUS)
+ if (cpu >= nr_cpu_ids)
goto err_out;
/* get the cpufreq driver */
@@ -149,7 +149,7 @@ struct cpufreq_policy *cpufreq_cpu_get(u
/* get the CPU */
- data = cpufreq_cpu_data[cpu];
+ data = per_cpu(cpufreq_cpu_data, cpu);
if (!data)
goto err_out_put_module;
@@ -327,7 +327,7 @@ void cpufreq_notify_transition(struct cp
dprintk("notification %u of frequency transition to %u kHz\n",
state, freqs->new);
- policy = cpufreq_cpu_data[freqs->cpu];
+ policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
switch (state) {
case CPUFREQ_PRECHANGE:
@@ -809,8 +809,8 @@ static int cpufreq_add_dev(struct sys_de
#ifdef CONFIG_SMP
#ifdef CONFIG_HOTPLUG_CPU
- if (cpufreq_cpu_governor[cpu]){
- policy->governor = cpufreq_cpu_governor[cpu];
+ if (per_cpu(cpufreq_cpu_governor, cpu)) {
+ policy->governor = per_cpu(cpufreq_cpu_governor, cpu);
dprintk("Restoring governor %s for cpu %d\n",
policy->governor->name, cpu);
}
@@ -835,7 +835,7 @@ static int cpufreq_add_dev(struct sys_de
spin_lock_irqsave(&cpufreq_driver_lock, flags);
managed_policy->cpus = policy->cpus;
- cpufreq_cpu_data[cpu] = managed_policy;
+ per_cpu(cpufreq_cpu_data, cpu) = managed_policy;
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
dprintk("CPU already managed, adding link\n");
@@ -880,7 +880,7 @@ static int cpufreq_add_dev(struct sys_de
spin_lock_irqsave(&cpufreq_driver_lock, flags);
for_each_cpu_mask(j, policy->cpus) {
- cpufreq_cpu_data[j] = policy;
+ per_cpu(cpufreq_cpu_data, j) = policy;
per_cpu(policy_cpu, j) = policy->cpu;
}
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
@@ -927,7 +927,7 @@ static int cpufreq_add_dev(struct sys_de
err_out_unregister:
spin_lock_irqsave(&cpufreq_driver_lock, flags);
for_each_cpu_mask(j, policy->cpus)
- cpufreq_cpu_data[j] = NULL;
+ per_cpu(cpufreq_cpu_data, j) = NULL;
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
kobject_put(&policy->kobj);
@@ -970,7 +970,7 @@ static int __cpufreq_remove_dev(struct s
dprintk("unregistering CPU %u\n", cpu);
spin_lock_irqsave(&cpufreq_driver_lock, flags);
- data = cpufreq_cpu_data[cpu];
+ data = per_cpu(cpufreq_cpu_data, cpu);
if (!data) {
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
@@ -978,7 +978,7 @@ static int __cpufreq_remove_dev(struct s
unlock_policy_rwsem_write(cpu);
return -EINVAL;
}
- cpufreq_cpu_data[cpu] = NULL;
+ per_cpu(cpufreq_cpu_data, cpu) = NULL;
#ifdef CONFIG_SMP
@@ -1000,19 +1000,19 @@ static int __cpufreq_remove_dev(struct s
#ifdef CONFIG_SMP
#ifdef CONFIG_HOTPLUG_CPU
- cpufreq_cpu_governor[cpu] = data->governor;
+ per_cpu(cpufreq_cpu_governor, cpu) = data->governor;
#endif
/* if we have other CPUs still registered, we need to unlink them,
* or else wait_for_completion below will lock up. Clean the
- * cpufreq_cpu_data[] while holding the lock, and remove the sysfs
- * links afterwards.
+ * per_cpu(cpufreq_cpu_data) while holding the lock, and remove
+ * the sysfs links afterwards.
*/
if (unlikely(cpus_weight(data->cpus) > 1)) {
for_each_cpu_mask(j, data->cpus) {
if (j == cpu)
continue;
- cpufreq_cpu_data[j] = NULL;
+ per_cpu(cpufreq_cpu_data, j) = NULL;
}
}
@@ -1024,7 +1024,7 @@ static int __cpufreq_remove_dev(struct s
continue;
dprintk("removing link for cpu %u\n", j);
#ifdef CONFIG_HOTPLUG_CPU
- cpufreq_cpu_governor[j] = data->governor;
+ per_cpu(cpufreq_cpu_governor, j) = data->governor;
#endif
cpu_sys_dev = get_cpu_sysdev(j);
sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
@@ -1134,7 +1134,7 @@ EXPORT_SYMBOL(cpufreq_quick_get);
static unsigned int __cpufreq_get(unsigned int cpu)
{
- struct cpufreq_policy *policy = cpufreq_cpu_data[cpu];
+ struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
unsigned int ret_freq = 0;
if (!cpufreq_driver->get)
@@ -1803,16 +1803,19 @@ int cpufreq_register_driver(struct cpufr
cpufreq_driver = driver_data;
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
- ret = sysdev_driver_register(&cpu_sysdev_class,&cpufreq_sysdev_driver);
+ ret = sysdev_driver_register(&cpu_sysdev_class,
+ &cpufreq_sysdev_driver);
if ((!ret) && !(cpufreq_driver->flags & CPUFREQ_STICKY)) {
int i;
ret = -ENODEV;
/* check for at least one working CPU */
- for (i=0; i<NR_CPUS; i++)
- if (cpufreq_cpu_data[i])
+ for (i = 0; i < nr_cpu_ids; i++)
+ if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
ret = 0;
+ break;
+ }
/* if all ->init() calls failed, unregister */
if (ret) {
--- linux-2.6.25-rc5.orig/drivers/cpufreq/cpufreq_stats.c
+++ linux-2.6.25-rc5/drivers/cpufreq/cpufreq_stats.c
@@ -43,7 +43,7 @@ struct cpufreq_stats {
#endif
};
-static struct cpufreq_stats *cpufreq_stats_table[NR_CPUS];
+static DEFINE_PER_CPU(struct cpufreq_stats *, cpufreq_stats_table);
struct cpufreq_stats_attribute {
struct attribute attr;
@@ -58,7 +58,7 @@ cpufreq_stats_update (unsigned int cpu)
cur_time = get_jiffies_64();
spin_lock(&cpufreq_stats_lock);
- stat = cpufreq_stats_table[cpu];
+ stat = per_cpu(cpufreq_stats_table, cpu);
if (stat->time_in_state)
stat->time_in_state[stat->last_index] =
cputime64_add(stat->time_in_state[stat->last_index],
@@ -71,11 +71,11 @@ cpufreq_stats_update (unsigned int cpu)
static ssize_t
show_total_trans(struct cpufreq_policy *policy, char *buf)
{
- struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+ struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu);
if (!stat)
return 0;
return sprintf(buf, "%d\n",
- cpufreq_stats_table[stat->cpu]->total_trans);
+ per_cpu(cpufreq_stats_table, stat->cpu)->total_trans);
}
static ssize_t
@@ -83,7 +83,7 @@ show_time_in_state(struct cpufreq_policy
{
ssize_t len = 0;
int i;
- struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+ struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu);
if (!stat)
return 0;
cpufreq_stats_update(stat->cpu);
@@ -101,7 +101,7 @@ show_trans_table(struct cpufreq_policy *
ssize_t len = 0;
int i, j;
- struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+ struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu);
if (!stat)
return 0;
cpufreq_stats_update(stat->cpu);
@@ -170,7 +170,7 @@ freq_table_get_index(struct cpufreq_stat
static void cpufreq_stats_free_table(unsigned int cpu)
{
- struct cpufreq_stats *stat = cpufreq_stats_table[cpu];
+ struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, cpu);
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
if (policy && policy->cpu == cpu)
sysfs_remove_group(&policy->kobj, &stats_attr_group);
@@ -178,7 +178,7 @@ static void cpufreq_stats_free_table(uns
kfree(stat->time_in_state);
kfree(stat);
}
- cpufreq_stats_table[cpu] = NULL;
+ per_cpu(cpufreq_stats_table, cpu) = NULL;
if (policy)
cpufreq_cpu_put(policy);
}
@@ -192,7 +192,7 @@ cpufreq_stats_create_table (struct cpufr
struct cpufreq_policy *data;
unsigned int alloc_size;
unsigned int cpu = policy->cpu;
- if (cpufreq_stats_table[cpu])
+ if (per_cpu(cpufreq_stats_table, cpu))
return -EBUSY;
if ((stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL)
return -ENOMEM;
@@ -207,7 +207,7 @@ cpufreq_stats_create_table (struct cpufr
goto error_out;
stat->cpu = cpu;
- cpufreq_stats_table[cpu] = stat;
+ per_cpu(cpufreq_stats_table, cpu) = stat;
for (i=0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
unsigned int freq = table[i].frequency;
@@ -251,7 +251,7 @@ error_out:
cpufreq_cpu_put(data);
error_get_fail:
kfree(stat);
- cpufreq_stats_table[cpu] = NULL;
+ per_cpu(cpufreq_stats_table, cpu) = NULL;
return ret;
}
@@ -284,7 +284,7 @@ cpufreq_stat_notifier_trans (struct noti
if (val != CPUFREQ_POSTCHANGE)
return 0;
- stat = cpufreq_stats_table[freq->cpu];
+ stat = per_cpu(cpufreq_stats_table, freq->cpu);
if (!stat)
return 0;
--- linux-2.6.25-rc5.orig/drivers/cpufreq/freq_table.c
+++ linux-2.6.25-rc5/drivers/cpufreq/freq_table.c
@@ -169,7 +169,7 @@ int cpufreq_frequency_table_target(struc
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
-static struct cpufreq_frequency_table *show_table[NR_CPUS];
+static DEFINE_PER_CPU(struct cpufreq_frequency_table *, show_table);
/**
* show_available_freqs - show available frequencies for the specified CPU
*/
@@ -180,10 +180,10 @@ static ssize_t show_available_freqs (str
ssize_t count = 0;
struct cpufreq_frequency_table *table;
- if (!show_table[cpu])
+ if (!per_cpu(show_table, cpu))
return -ENODEV;
- table = show_table[cpu];
+ table = per_cpu(show_table, cpu);
for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
@@ -212,20 +212,20 @@ void cpufreq_frequency_table_get_attr(st
unsigned int cpu)
{
dprintk("setting show_table for cpu %u to %p\n", cpu, table);
- show_table[cpu] = table;
+ per_cpu(show_table, cpu) = table;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_attr);
void cpufreq_frequency_table_put_attr(unsigned int cpu)
{
dprintk("clearing show_table for cpu %u\n", cpu);
- show_table[cpu] = NULL;
+ per_cpu(show_table, cpu) = NULL;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr);
struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
{
- return show_table[cpu];
+ return per_cpu(show_table, cpu);
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 04/10] acpi: change processors from array to per_cpu variable
2008-03-25 2:19 [PATCH 00/10] NR_CPUS: third reduction of NR_CPUS memory usage Mike Travis
` (2 preceding siblings ...)
2008-03-25 2:19 ` [PATCH 03/10] cpufreq: change cpu freq arrays to per_cpu variables Mike Travis
@ 2008-03-25 2:19 ` Mike Travis
2008-03-25 2:19 ` [PATCH 05/10] cpumask: Add cpumask_scnprintf_len function Mike Travis
` (5 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Mike Travis @ 2008-03-25 2:19 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-mm, linux-kernel, Len Brown
[-- Attachment #1: nr_cpus-in-acpi-driver-cpu_alloc --]
[-- Type: text/plain, Size: 8095 bytes --]
Change processors from an array sized by NR_CPUS to a per_cpu variable.
Based on linux-2.6.25-rc5-mm1
Cc: Len Brown <len.brown@intel.com>
Signed-off-by: Mike Travis <travis@sgi.com>
---
drivers/acpi/processor_core.c | 18 ++++++++----------
drivers/acpi/processor_idle.c | 8 ++++----
drivers/acpi/processor_perflib.c | 18 +++++++++---------
drivers/acpi/processor_throttling.c | 14 +++++++-------
include/acpi/processor.h | 2 +-
5 files changed, 29 insertions(+), 31 deletions(-)
--- linux-2.6.25-rc5.orig/drivers/acpi/processor_core.c
+++ linux-2.6.25-rc5/drivers/acpi/processor_core.c
@@ -118,7 +118,7 @@ static const struct file_operations acpi
.release = single_release,
};
-struct acpi_processor *processors[NR_CPUS];
+DEFINE_PER_CPU(struct acpi_processor *, processors);
struct acpi_processor_errata errata __read_mostly;
/* --------------------------------------------------------------------------
@@ -615,7 +615,7 @@ static int acpi_processor_get_info(struc
return 0;
}
-static void *processor_device_array[NR_CPUS];
+static DEFINE_PER_CPU(void *, processor_device_array);
static int __cpuinit acpi_processor_start(struct acpi_device *device)
{
@@ -639,15 +639,15 @@ static int __cpuinit acpi_processor_star
* ACPI id of processors can be reported wrongly by the BIOS.
* Don't trust it blindly
*/
- if (processor_device_array[pr->id] != NULL &&
- processor_device_array[pr->id] != device) {
+ if (per_cpu(processor_device_array, pr->id) != NULL &&
+ per_cpu(processor_device_array, pr->id) != device) {
printk(KERN_WARNING "BIOS reported wrong ACPI id "
"for the processor\n");
return -ENODEV;
}
- processor_device_array[pr->id] = device;
+ per_cpu(processor_device_array, pr->id) = device;
- processors[pr->id] = pr;
+ per_cpu(processors, pr->id) = pr;
result = acpi_processor_add_fs(device);
if (result)
@@ -751,7 +751,7 @@ static int acpi_cpu_soft_notify(struct n
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
- struct acpi_processor *pr = processors[cpu];
+ struct acpi_processor *pr = per_cpu(processors, cpu);
if (action == CPU_ONLINE && pr) {
acpi_processor_ppc_has_changed(pr);
@@ -821,7 +821,7 @@ static int acpi_processor_remove(struct
pr->cdev = NULL;
}
- processors[pr->id] = NULL;
+ per_cpu(processors, pr->id) = NULL;
kfree(pr);
@@ -1070,8 +1070,6 @@ static int __init acpi_processor_init(vo
{
int result = 0;
-
- memset(&processors, 0, sizeof(processors));
memset(&errata, 0, sizeof(errata));
#ifdef CONFIG_SMP
--- linux-2.6.25-rc5.orig/drivers/acpi/processor_idle.c
+++ linux-2.6.25-rc5/drivers/acpi/processor_idle.c
@@ -417,7 +417,7 @@ static void acpi_processor_idle(void)
*/
local_irq_disable();
- pr = processors[smp_processor_id()];
+ pr = __get_cpu_var(processors);
if (!pr) {
local_irq_enable();
return;
@@ -1438,7 +1438,7 @@ static int acpi_idle_enter_c1(struct cpu
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- pr = processors[smp_processor_id()];
+ pr = __get_cpu_var(processors);
if (unlikely(!pr))
return 0;
@@ -1478,7 +1478,7 @@ static int acpi_idle_enter_simple(struct
u32 t1, t2;
int sleep_ticks = 0;
- pr = processors[smp_processor_id()];
+ pr = __get_cpu_var(processors);
if (unlikely(!pr))
return 0;
@@ -1557,7 +1557,7 @@ static int acpi_idle_enter_bm(struct cpu
u32 t1, t2;
int sleep_ticks = 0;
- pr = processors[smp_processor_id()];
+ pr = __get_cpu_var(processors);
if (unlikely(!pr))
return 0;
--- linux-2.6.25-rc5.orig/drivers/acpi/processor_perflib.c
+++ linux-2.6.25-rc5/drivers/acpi/processor_perflib.c
@@ -89,7 +89,7 @@ static int acpi_processor_ppc_notifier(s
if (event != CPUFREQ_INCOMPATIBLE)
goto out;
- pr = processors[policy->cpu];
+ pr = per_cpu(processors, policy->cpu);
if (!pr || !pr->performance)
goto out;
@@ -577,7 +577,7 @@ int acpi_processor_preregister_performan
/* Call _PSD for all CPUs */
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr) {
/* Look only at processors in ACPI namespace */
continue;
@@ -608,7 +608,7 @@ int acpi_processor_preregister_performan
* domain info.
*/
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr)
continue;
@@ -629,7 +629,7 @@ int acpi_processor_preregister_performan
cpus_clear(covered_cpus);
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr)
continue;
@@ -656,7 +656,7 @@ int acpi_processor_preregister_performan
if (i == j)
continue;
- match_pr = processors[j];
+ match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@@ -685,7 +685,7 @@ int acpi_processor_preregister_performan
if (i == j)
continue;
- match_pr = processors[j];
+ match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@@ -702,7 +702,7 @@ int acpi_processor_preregister_performan
err_ret:
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr || !pr->performance)
continue;
@@ -733,7 +733,7 @@ acpi_processor_register_performance(stru
mutex_lock(&performance_mutex);
- pr = processors[cpu];
+ pr = per_cpu(processors, cpu);
if (!pr) {
mutex_unlock(&performance_mutex);
return -ENODEV;
@@ -771,7 +771,7 @@ acpi_processor_unregister_performance(st
mutex_lock(&performance_mutex);
- pr = processors[cpu];
+ pr = per_cpu(processors, cpu);
if (!pr) {
mutex_unlock(&performance_mutex);
return;
--- linux-2.6.25-rc5.orig/drivers/acpi/processor_throttling.c
+++ linux-2.6.25-rc5/drivers/acpi/processor_throttling.c
@@ -71,7 +71,7 @@ static int acpi_processor_update_tsd_coo
* coordination between all CPUs.
*/
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr)
continue;
@@ -93,7 +93,7 @@ static int acpi_processor_update_tsd_coo
cpus_clear(covered_cpus);
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr)
continue;
@@ -119,7 +119,7 @@ static int acpi_processor_update_tsd_coo
if (i == j)
continue;
- match_pr = processors[j];
+ match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@@ -152,7 +152,7 @@ static int acpi_processor_update_tsd_coo
if (i == j)
continue;
- match_pr = processors[j];
+ match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@@ -172,7 +172,7 @@ static int acpi_processor_update_tsd_coo
err_ret:
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr)
continue;
@@ -214,7 +214,7 @@ static int acpi_processor_throttling_not
struct acpi_processor_throttling *p_throttling;
cpu = p_tstate->cpu;
- pr = processors[cpu];
+ pr = per_cpu(processors, cpu);
if (!pr) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid pr pointer\n"));
return 0;
@@ -1035,7 +1035,7 @@ int acpi_processor_set_throttling(struct
* cpus.
*/
for_each_cpu_mask(i, online_throttling_cpus) {
- match_pr = processors[i];
+ match_pr = per_cpu(processors, i);
/*
* If the pointer is invalid, we will report the
* error message and continue.
--- linux-2.6.25-rc5.orig/include/acpi/processor.h
+++ linux-2.6.25-rc5/include/acpi/processor.h
@@ -255,7 +255,7 @@ extern void acpi_processor_unregister_pe
int acpi_processor_notify_smm(struct module *calling_module);
/* for communication between multiple parts of the processor kernel module */
-extern struct acpi_processor *processors[NR_CPUS];
+DECLARE_PER_CPU(struct acpi_processor *, processors);
extern struct acpi_processor_errata errata;
void arch_acpi_processor_init_pdc(struct acpi_processor *pr);
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 05/10] cpumask: Add cpumask_scnprintf_len function
2008-03-25 2:19 [PATCH 00/10] NR_CPUS: third reduction of NR_CPUS memory usage Mike Travis
` (3 preceding siblings ...)
2008-03-25 2:19 ` [PATCH 04/10] acpi: change processors from array to per_cpu variable Mike Travis
@ 2008-03-25 2:19 ` Mike Travis
2008-03-25 2:20 ` [PATCH 06/10] x86: reduce memory and stack usage in intel_cacheinfo Mike Travis
` (4 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Mike Travis @ 2008-03-25 2:19 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-mm, linux-kernel, Paul Jackson
[-- Attachment #1: add-cpumask_scnprintf_len --]
[-- Type: text/plain, Size: 2783 bytes --]
Add a new function cpumask_scnprintf_len() to return the number of
characters needed to display "len" cpumask bits. The current method
of allocating NR_CPUS bytes is incorrect as what's really needed is
9 characters per 32-bit word of cpumask bits (8 hex digits plus the
seperator [','] or the terminating NULL.) This function provides the
caller the means to allocate the correct string length.
Based on linux-2.6.25-rc5-mm1
Cc: Paul Jackson <pj@sgi.com>
Signed-off-by: Mike Travis <travis@sgi.com>
---
include/linux/bitmap.h | 1 +
include/linux/cpumask.h | 7 +++++++
lib/bitmap.c | 16 ++++++++++++++++
3 files changed, 24 insertions(+)
--- linux-2.6.25-rc5.orig/include/linux/bitmap.h
+++ linux-2.6.25-rc5/include/linux/bitmap.h
@@ -110,6 +110,7 @@ extern int __bitmap_weight(const unsigne
extern int bitmap_scnprintf(char *buf, unsigned int len,
const unsigned long *src, int nbits);
+extern int bitmap_scnprintf_len(unsigned int len);
extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
unsigned long *dst, int nbits);
extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,
--- linux-2.6.25-rc5.orig/include/linux/cpumask.h
+++ linux-2.6.25-rc5/include/linux/cpumask.h
@@ -277,6 +277,13 @@ static inline int __cpumask_scnprintf(ch
return bitmap_scnprintf(buf, len, srcp->bits, nbits);
}
+#define cpumask_scnprintf_len(len) \
+ __cpumask_scnprintf_len((len))
+static inline int __cpumask_scnprintf_len(int len)
+{
+ return bitmap_scnprintf_len(len);
+}
+
#define cpumask_parse_user(ubuf, ulen, dst) \
__cpumask_parse_user((ubuf), (ulen), &(dst), NR_CPUS)
static inline int __cpumask_parse_user(const char __user *buf, int len,
--- linux-2.6.25-rc5.orig/lib/bitmap.c
+++ linux-2.6.25-rc5/lib/bitmap.c
@@ -316,6 +316,22 @@ int bitmap_scnprintf(char *buf, unsigned
EXPORT_SYMBOL(bitmap_scnprintf);
/**
+ * bitmap_scnprintf_len - return buffer length needed to convert
+ * bitmap to an ASCII hex string.
+ * @len: number of bits to be converted
+ */
+int bitmap_scnprintf_len(unsigned int len)
+{
+ /* we need 9 chars per word for 32 bit words (8 hexdigits + sep/null) */
+ int bitslen = ALIGN(len, CHUNKSZ);
+ int wordlen = CHUNKSZ / 4;
+ int buflen = (bitslen / wordlen) * (wordlen + 1) * sizeof(char);
+
+ return buflen;
+}
+EXPORT_SYMBOL(bitmap_scnprintf_len);
+
+/**
* __bitmap_parse - convert an ASCII hex string into a bitmap.
* @buf: pointer to buffer containing string.
* @buflen: buffer size in bytes. If string is smaller than this
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 06/10] x86: reduce memory and stack usage in intel_cacheinfo
2008-03-25 2:19 [PATCH 00/10] NR_CPUS: third reduction of NR_CPUS memory usage Mike Travis
` (4 preceding siblings ...)
2008-03-25 2:19 ` [PATCH 05/10] cpumask: Add cpumask_scnprintf_len function Mike Travis
@ 2008-03-25 2:20 ` Mike Travis
2008-03-25 2:20 ` [PATCH 07/10] cpu: change cpu_sys_devices from array to per_cpu variable Mike Travis
` (3 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Mike Travis @ 2008-03-25 2:20 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, linux-kernel, Thomas Gleixner, Ingo Molnar,
H. Peter Anvin, Andi Kleen
[-- Attachment #1: nr_cpus-in-intel_cacheinfo --]
[-- Type: text/plain, Size: 7251 bytes --]
* Change the following static arrays sized by NR_CPUS to
per_cpu data variables:
_cpuid4_info *cpuid4_info[NR_CPUS];
_index_kobject *index_kobject[NR_CPUS];
kobject * cache_kobject[NR_CPUS];
* Remove the local NR_CPUS array with a kmalloc'd region in
show_shared_cpu_map().
Also some minor complaints from checkpatch.pl fixed.
Based on linux-2.6.25-rc5-mm1
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Mike Travis <travis@sgi.com>
---
arch/x86/kernel/cpu/intel_cacheinfo.c | 70 +++++++++++++++++++---------------
1 file changed, 40 insertions(+), 30 deletions(-)
--- linux-2.6.25-rc5.orig/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ linux-2.6.25-rc5/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -129,7 +129,7 @@ struct _cpuid4_info {
union _cpuid4_leaf_ebx ebx;
union _cpuid4_leaf_ecx ecx;
unsigned long size;
- cpumask_t shared_cpu_map;
+ cpumask_t shared_cpu_map; /* future?: only cpus/node is needed */
};
unsigned short num_cache_leaves;
@@ -451,8 +451,8 @@ unsigned int __cpuinit init_intel_cachei
}
/* pointer to _cpuid4_info array (for each cache leaf) */
-static struct _cpuid4_info *cpuid4_info[NR_CPUS];
-#define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y]))
+static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
+#define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y]))
#ifdef CONFIG_SMP
static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
@@ -474,7 +474,7 @@ static void __cpuinit cache_shared_cpu_m
if (cpu_data(i).apicid >> index_msb ==
c->apicid >> index_msb) {
cpu_set(i, this_leaf->shared_cpu_map);
- if (i != cpu && cpuid4_info[i]) {
+ if (i != cpu && per_cpu(cpuid4_info, i)) {
sibling_leaf = CPUID4_INFO_IDX(i, index);
cpu_set(cpu, sibling_leaf->shared_cpu_map);
}
@@ -505,8 +505,8 @@ static void __cpuinit free_cache_attribu
for (i = 0; i < num_cache_leaves; i++)
cache_remove_shared_cpu_map(cpu, i);
- kfree(cpuid4_info[cpu]);
- cpuid4_info[cpu] = NULL;
+ kfree(per_cpu(cpuid4_info, cpu));
+ per_cpu(cpuid4_info, cpu) = NULL;
}
static int __cpuinit detect_cache_attributes(unsigned int cpu)
@@ -519,9 +519,9 @@ static int __cpuinit detect_cache_attrib
if (num_cache_leaves == 0)
return -ENOENT;
- cpuid4_info[cpu] = kzalloc(
+ per_cpu(cpuid4_info, cpu) = kzalloc(
sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
- if (cpuid4_info[cpu] == NULL)
+ if (per_cpu(cpuid4_info, cpu) == NULL)
return -ENOMEM;
oldmask = current->cpus_allowed;
@@ -546,8 +546,8 @@ static int __cpuinit detect_cache_attrib
out:
if (retval) {
- kfree(cpuid4_info[cpu]);
- cpuid4_info[cpu] = NULL;
+ kfree(per_cpu(cpuid4_info, cpu));
+ per_cpu(cpuid4_info, cpu) = NULL;
}
return retval;
@@ -561,7 +561,7 @@ out:
extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
/* pointer to kobject for cpuX/cache */
-static struct kobject * cache_kobject[NR_CPUS];
+static DEFINE_PER_CPU(struct kobject *, cache_kobject);
struct _index_kobject {
struct kobject kobj;
@@ -570,8 +570,8 @@ struct _index_kobject {
};
/* pointer to array of kobjects for cpuX/cache/indexY */
-static struct _index_kobject *index_kobject[NR_CPUS];
-#define INDEX_KOBJECT_PTR(x,y) (&((index_kobject[x])[y]))
+static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
+#define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(index_kobject, x))[y]))
#define show_one_plus(file_name, object, val) \
static ssize_t show_##file_name \
@@ -593,9 +593,16 @@ static ssize_t show_size(struct _cpuid4_
static ssize_t show_shared_cpu_map(struct _cpuid4_info *this_leaf, char *buf)
{
- char mask_str[NR_CPUS];
- cpumask_scnprintf(mask_str, NR_CPUS, this_leaf->shared_cpu_map);
- return sprintf(buf, "%s\n", mask_str);
+ int n = 0;
+ int len = cpumask_scnprintf_len(nr_cpu_ids);
+ char *mask_str = kmalloc(len, GFP_KERNEL);
+
+ if (mask_str) {
+ cpumask_scnprintf(mask_str, len, this_leaf->shared_cpu_map);
+ n = sprintf(buf, "%s\n", mask_str);
+ kfree(mask_str);
+ }
+ return n;
}
static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) {
@@ -684,10 +691,10 @@ static struct kobj_type ktype_percpu_ent
static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
{
- kfree(cache_kobject[cpu]);
- kfree(index_kobject[cpu]);
- cache_kobject[cpu] = NULL;
- index_kobject[cpu] = NULL;
+ kfree(per_cpu(cache_kobject, cpu));
+ kfree(per_cpu(index_kobject, cpu));
+ per_cpu(cache_kobject, cpu) = NULL;
+ per_cpu(index_kobject, cpu) = NULL;
free_cache_attributes(cpu);
}
@@ -703,13 +710,14 @@ static int __cpuinit cpuid4_cache_sysfs_
return err;
/* Allocate all required memory */
- cache_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL);
- if (unlikely(cache_kobject[cpu] == NULL))
+ per_cpu(cache_kobject, cpu) =
+ kzalloc(sizeof(struct kobject), GFP_KERNEL);
+ if (unlikely(per_cpu(cache_kobject, cpu) == NULL))
goto err_out;
- index_kobject[cpu] = kzalloc(
+ per_cpu(index_kobject, cpu) = kzalloc(
sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
- if (unlikely(index_kobject[cpu] == NULL))
+ if (unlikely(per_cpu(index_kobject, cpu) == NULL))
goto err_out;
return 0;
@@ -733,7 +741,8 @@ static int __cpuinit cache_add_dev(struc
if (unlikely(retval < 0))
return retval;
- retval = kobject_init_and_add(cache_kobject[cpu], &ktype_percpu_entry,
+ retval = kobject_init_and_add(per_cpu(cache_kobject, cpu),
+ &ktype_percpu_entry,
&sys_dev->kobj, "%s", "cache");
if (retval < 0) {
cpuid4_cache_sysfs_exit(cpu);
@@ -745,13 +754,14 @@ static int __cpuinit cache_add_dev(struc
this_object->cpu = cpu;
this_object->index = i;
retval = kobject_init_and_add(&(this_object->kobj),
- &ktype_cache, cache_kobject[cpu],
+ &ktype_cache,
+ per_cpu(cache_kobject, cpu),
"index%1lu", i);
if (unlikely(retval)) {
for (j = 0; j < i; j++) {
kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj));
}
- kobject_put(cache_kobject[cpu]);
+ kobject_put(per_cpu(cache_kobject, cpu));
cpuid4_cache_sysfs_exit(cpu);
break;
}
@@ -760,7 +770,7 @@ static int __cpuinit cache_add_dev(struc
if (!retval)
cpu_set(cpu, cache_dev_map);
- kobject_uevent(cache_kobject[cpu], KOBJ_ADD);
+ kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
return retval;
}
@@ -769,7 +779,7 @@ static void __cpuinit cache_remove_dev(s
unsigned int cpu = sys_dev->id;
unsigned long i;
- if (cpuid4_info[cpu] == NULL)
+ if (per_cpu(cpuid4_info, cpu) == NULL)
return;
if (!cpu_isset(cpu, cache_dev_map))
return;
@@ -777,7 +787,7 @@ static void __cpuinit cache_remove_dev(s
for (i = 0; i < num_cache_leaves; i++)
kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
- kobject_put(cache_kobject[cpu]);
+ kobject_put(per_cpu(cache_kobject, cpu));
cpuid4_cache_sysfs_exit(cpu);
}
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 07/10] cpu: change cpu_sys_devices from array to per_cpu variable
2008-03-25 2:19 [PATCH 00/10] NR_CPUS: third reduction of NR_CPUS memory usage Mike Travis
` (5 preceding siblings ...)
2008-03-25 2:20 ` [PATCH 06/10] x86: reduce memory and stack usage in intel_cacheinfo Mike Travis
@ 2008-03-25 2:20 ` Mike Travis
2008-03-25 2:20 ` [PATCH 08/10] net: remove NR_CPUS arrays in net/core/dev.c Mike Travis
` (2 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Mike Travis @ 2008-03-25 2:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-mm, linux-kernel
[-- Attachment #1: nr_cpus-in-cpu_c --]
[-- Type: text/plain, Size: 1743 bytes --]
Change cpu_sys_devices from array to per_cpu variable in
drivers/base/cpu.c.
Based on linux-2.6.25-rc5-mm1
(MAINTAINER unknown)
Signed-off-by: Mike Travis <travis@sgi.com>
---
drivers/base/cpu.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
--- linux-2.6.25-rc5.orig/drivers/base/cpu.c
+++ linux-2.6.25-rc5/drivers/base/cpu.c
@@ -18,7 +18,7 @@ struct sysdev_class cpu_sysdev_class = {
};
EXPORT_SYMBOL(cpu_sysdev_class);
-static struct sys_device *cpu_sys_devices[NR_CPUS];
+static DEFINE_PER_CPU(struct sys_device *, cpu_sys_devices);
#ifdef CONFIG_HOTPLUG_CPU
static ssize_t show_online(struct sys_device *dev, char *buf)
@@ -68,7 +68,7 @@ void unregister_cpu(struct cpu *cpu)
sysdev_remove_file(&cpu->sysdev, &attr_online);
sysdev_unregister(&cpu->sysdev);
- cpu_sys_devices[logical_cpu] = NULL;
+ per_cpu(cpu_sys_devices, logical_cpu) = NULL;
return;
}
#else /* ... !CONFIG_HOTPLUG_CPU */
@@ -122,7 +122,7 @@ int __cpuinit register_cpu(struct cpu *c
if (!error && cpu->hotpluggable)
register_cpu_control(cpu);
if (!error)
- cpu_sys_devices[num] = &cpu->sysdev;
+ per_cpu(cpu_sys_devices, num) = &cpu->sysdev;
if (!error)
register_cpu_under_node(num, cpu_to_node(num));
@@ -135,8 +135,8 @@ int __cpuinit register_cpu(struct cpu *c
struct sys_device *get_cpu_sysdev(unsigned cpu)
{
- if (cpu < NR_CPUS)
- return cpu_sys_devices[cpu];
+ if (cpu < nr_cpu_ids && cpu_possible(cpu))
+ return per_cpu(cpu_sys_devices, cpu);
else
return NULL;
}
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 08/10] net: remove NR_CPUS arrays in net/core/dev.c
2008-03-25 2:19 [PATCH 00/10] NR_CPUS: third reduction of NR_CPUS memory usage Mike Travis
` (6 preceding siblings ...)
2008-03-25 2:20 ` [PATCH 07/10] cpu: change cpu_sys_devices from array to per_cpu variable Mike Travis
@ 2008-03-25 2:20 ` Mike Travis
2008-03-25 5:57 ` Alexey Dobriyan
2008-03-25 2:20 ` [PATCH 09/10] x86: oprofile: remove NR_CPUS arrays in arch/x86/oprofile/nmi_int.c Mike Travis
2008-03-25 2:20 ` [PATCH 10/10] sched: Remove fixed NR_CPUS sized arrays in kernel_sched.c Mike Travis
9 siblings, 1 reply; 13+ messages in thread
From: Mike Travis @ 2008-03-25 2:20 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, linux-kernel, David S. Miller, Alexey Kuznetsov,
James Morris, Patrick McHardy
[-- Attachment #1: nr_cpus-in-net_core_dev --]
[-- Type: text/plain, Size: 2201 bytes --]
Remove the fixed size channels[NR_CPUS] array in
net/core/dev.c and dynamically allocate array based on
nr_cpu_ids.
Based on linux-2.6.25-rc5-mm1
Cc: David S. Miller <davem@davemloft.net>
Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Cc: James Morris <jmorris@namei.org>
Cc: Patrick McHardy <kaber@trash.net>
Signed-off-by: Mike Travis <travis@sgi.com>
---
net/core/dev.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
--- linux-2.6.25-rc5.orig/net/core/dev.c
+++ linux-2.6.25-rc5/net/core/dev.c
@@ -162,7 +162,7 @@ struct net_dma {
struct dma_client client;
spinlock_t lock;
cpumask_t channel_mask;
- struct dma_chan *channels[NR_CPUS];
+ struct dma_chan **channels;
};
static enum dma_state_client
@@ -2448,7 +2448,7 @@ static struct netif_rx_stats *softnet_ge
{
struct netif_rx_stats *rc = NULL;
- while (*pos < NR_CPUS)
+ while (*pos < nr_cpu_ids)
if (cpu_online(*pos)) {
rc = &per_cpu(netdev_rx_stat, *pos);
break;
@@ -4320,7 +4320,7 @@ netdev_dma_event(struct dma_client *clie
spin_lock(&net_dma->lock);
switch (state) {
case DMA_RESOURCE_AVAILABLE:
- for (i = 0; i < NR_CPUS; i++)
+ for (i = 0; i < nr_cpu_ids; i++)
if (net_dma->channels[i] == chan) {
found = 1;
break;
@@ -4335,7 +4335,7 @@ netdev_dma_event(struct dma_client *clie
}
break;
case DMA_RESOURCE_REMOVED:
- for (i = 0; i < NR_CPUS; i++)
+ for (i = 0; i < nr_cpu_ids; i++)
if (net_dma->channels[i] == chan) {
found = 1;
pos = i;
@@ -4362,6 +4362,13 @@ netdev_dma_event(struct dma_client *clie
*/
static int __init netdev_dma_register(void)
{
+ net_dma.channels = kzalloc(nr_cpu_ids * sizeof(struct net_dma),
+ GFP_KERNEL);
+ if (unlikely(net_dma.channels)) {
+ printk(KERN_NOTICE
+ "netdev_dma: no memory for net_dma.channels\n");
+ return -ENOMEM;
+ }
spin_lock_init(&net_dma.lock);
dma_cap_set(DMA_MEMCPY, net_dma.client.cap_mask);
dma_async_client_register(&net_dma.client);
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 08/10] net: remove NR_CPUS arrays in net/core/dev.c
2008-03-25 2:20 ` [PATCH 08/10] net: remove NR_CPUS arrays in net/core/dev.c Mike Travis
@ 2008-03-25 5:57 ` Alexey Dobriyan
2008-03-25 15:02 ` Mike Travis
0 siblings, 1 reply; 13+ messages in thread
From: Alexey Dobriyan @ 2008-03-25 5:57 UTC (permalink / raw)
To: Mike Travis
Cc: Andrew Morton, linux-mm, linux-kernel, David S. Miller,
Alexey Kuznetsov, James Morris, Patrick McHardy
On Mon, Mar 24, 2008 at 07:20:02PM -0700, Mike Travis wrote:
> Remove the fixed size channels[NR_CPUS] array in
> net/core/dev.c and dynamically allocate array based on
> nr_cpu_ids.
> @@ -4362,6 +4362,13 @@ netdev_dma_event(struct dma_client *clie
> */
> static int __init netdev_dma_register(void)
> {
> + net_dma.channels = kzalloc(nr_cpu_ids * sizeof(struct net_dma),
> + GFP_KERNEL);
> + if (unlikely(net_dma.channels)) {
!net_dma.channels
> + printk(KERN_NOTICE
> + "netdev_dma: no memory for net_dma.channels\n");
> + return -ENOMEM;
> + }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 08/10] net: remove NR_CPUS arrays in net/core/dev.c
2008-03-25 5:57 ` Alexey Dobriyan
@ 2008-03-25 15:02 ` Mike Travis
0 siblings, 0 replies; 13+ messages in thread
From: Mike Travis @ 2008-03-25 15:02 UTC (permalink / raw)
To: Alexey Dobriyan
Cc: Andrew Morton, linux-mm, linux-kernel, David S. Miller,
Alexey Kuznetsov, James Morris, Patrick McHardy
Alexey Dobriyan wrote:
> On Mon, Mar 24, 2008 at 07:20:02PM -0700, Mike Travis wrote:
>> Remove the fixed size channels[NR_CPUS] array in
>> net/core/dev.c and dynamically allocate array based on
>> nr_cpu_ids.
>
>> @@ -4362,6 +4362,13 @@ netdev_dma_event(struct dma_client *clie
>> */
>> static int __init netdev_dma_register(void)
>> {
>> + net_dma.channels = kzalloc(nr_cpu_ids * sizeof(struct net_dma),
>> + GFP_KERNEL);
>> + if (unlikely(net_dma.channels)) {
>
> !net_dma.channels
>
>> + printk(KERN_NOTICE
>> + "netdev_dma: no memory for net_dma.channels\n");
>> + return -ENOMEM;
>> + }
Got it, Thanks!
-Mike
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 09/10] x86: oprofile: remove NR_CPUS arrays in arch/x86/oprofile/nmi_int.c
2008-03-25 2:19 [PATCH 00/10] NR_CPUS: third reduction of NR_CPUS memory usage Mike Travis
` (7 preceding siblings ...)
2008-03-25 2:20 ` [PATCH 08/10] net: remove NR_CPUS arrays in net/core/dev.c Mike Travis
@ 2008-03-25 2:20 ` Mike Travis
2008-03-25 2:20 ` [PATCH 10/10] sched: Remove fixed NR_CPUS sized arrays in kernel_sched.c Mike Travis
9 siblings, 0 replies; 13+ messages in thread
From: Mike Travis @ 2008-03-25 2:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-mm, linux-kernel, Philippe Elie
[-- Attachment #1: nr_cpus-in-nmi_int_c --]
[-- Type: text/plain, Size: 5750 bytes --]
Change the following arrays sized by NR_CPUS to be PERCPU variables:
static struct op_msrs cpu_msrs[NR_CPUS];
static unsigned long saved_lvtpc[NR_CPUS];
Also some minor complaints from checkpatch.pl fixed.
Based on linux-2.6.25-rc5-mm1
Cc: Philippe Elie <phil.el@wanadoo.fr>
Signed-off-by: Mike Travis <travis@sgi.com>
---
All changes were transparent except for:
static void nmi_shutdown(void)
{
+ struct op_msrs *msrs = &__get_cpu_var(cpu_msrs);
nmi_enabled = 0;
on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
unregister_die_notifier(&profile_exceptions_nb);
- model->shutdown(cpu_msrs);
+ model->shutdown(msrs);
free_msrs();
}
The existing code passed a reference to cpu 0's instance of struct op_msrs
to model->shutdown, whilst the other functions are passed a reference to
<this cpu's> instance of a struct op_msrs. This seemed to be a bug to me
even though as long as cpu 0 and <this cpu> are of the same type it would
have the same effect...?
---
arch/x86/oprofile/nmi_int.c | 49 ++++++++++++++++++++++++--------------------
1 file changed, 27 insertions(+), 22 deletions(-)
--- linux-2.6.25-rc5.orig/arch/x86/oprofile/nmi_int.c
+++ linux-2.6.25-rc5/arch/x86/oprofile/nmi_int.c
@@ -23,8 +23,8 @@
#include "op_x86_model.h"
static struct op_x86_model_spec const *model;
-static struct op_msrs cpu_msrs[NR_CPUS];
-static unsigned long saved_lvtpc[NR_CPUS];
+static DEFINE_PER_CPU(struct op_msrs, cpu_msrs);
+static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
static int nmi_start(void);
static void nmi_stop(void);
@@ -89,7 +89,7 @@ static int profile_exceptions_notify(str
switch (val) {
case DIE_NMI:
- if (model->check_ctrs(args->regs, &cpu_msrs[cpu]))
+ if (model->check_ctrs(args->regs, &per_cpu(cpu_msrs, cpu)))
ret = NOTIFY_STOP;
break;
default:
@@ -126,7 +126,7 @@ static void nmi_cpu_save_registers(struc
static void nmi_save_registers(void *dummy)
{
int cpu = smp_processor_id();
- struct op_msrs *msrs = &cpu_msrs[cpu];
+ struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu);
nmi_cpu_save_registers(msrs);
}
@@ -134,10 +134,10 @@ static void free_msrs(void)
{
int i;
for_each_possible_cpu(i) {
- kfree(cpu_msrs[i].counters);
- cpu_msrs[i].counters = NULL;
- kfree(cpu_msrs[i].controls);
- cpu_msrs[i].controls = NULL;
+ kfree(per_cpu(cpu_msrs, i).counters);
+ per_cpu(cpu_msrs, i).counters = NULL;
+ kfree(per_cpu(cpu_msrs, i).controls);
+ per_cpu(cpu_msrs, i).controls = NULL;
}
}
@@ -149,13 +149,15 @@ static int allocate_msrs(void)
int i;
for_each_possible_cpu(i) {
- cpu_msrs[i].counters = kmalloc(counters_size, GFP_KERNEL);
- if (!cpu_msrs[i].counters) {
+ per_cpu(cpu_msrs, i).counters = kmalloc(counters_size,
+ GFP_KERNEL);
+ if (!per_cpu(cpu_msrs, i).counters) {
success = 0;
break;
}
- cpu_msrs[i].controls = kmalloc(controls_size, GFP_KERNEL);
- if (!cpu_msrs[i].controls) {
+ per_cpu(cpu_msrs, i).controls = kmalloc(controls_size,
+ GFP_KERNEL);
+ if (!per_cpu(cpu_msrs, i).controls) {
success = 0;
break;
}
@@ -170,11 +172,11 @@ static int allocate_msrs(void)
static void nmi_cpu_setup(void *dummy)
{
int cpu = smp_processor_id();
- struct op_msrs *msrs = &cpu_msrs[cpu];
+ struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu);
spin_lock(&oprofilefs_lock);
model->setup_ctrs(msrs);
spin_unlock(&oprofilefs_lock);
- saved_lvtpc[cpu] = apic_read(APIC_LVTPC);
+ per_cpu(saved_lvtpc, cpu) = apic_read(APIC_LVTPC);
apic_write(APIC_LVTPC, APIC_DM_NMI);
}
@@ -203,13 +205,15 @@ static int nmi_setup(void)
*/
/* Assume saved/restored counters are the same on all CPUs */
- model->fill_in_addresses(&cpu_msrs[0]);
+ model->fill_in_addresses(&per_cpu(cpu_msrs, 0));
for_each_possible_cpu(cpu) {
if (cpu != 0) {
- memcpy(cpu_msrs[cpu].counters, cpu_msrs[0].counters,
+ memcpy(per_cpu(cpu_msrs, cpu).counters,
+ per_cpu(cpu_msrs, 0).counters,
sizeof(struct op_msr) * model->num_counters);
- memcpy(cpu_msrs[cpu].controls, cpu_msrs[0].controls,
+ memcpy(per_cpu(cpu_msrs, cpu).controls,
+ per_cpu(cpu_msrs, 0).controls,
sizeof(struct op_msr) * model->num_controls);
}
@@ -249,7 +253,7 @@ static void nmi_cpu_shutdown(void *dummy
{
unsigned int v;
int cpu = smp_processor_id();
- struct op_msrs *msrs = &cpu_msrs[cpu];
+ struct op_msrs *msrs = &__get_cpu_var(cpu_msrs);
/* restoring APIC_LVTPC can trigger an apic error because the delivery
* mode and vector nr combination can be illegal. That's by design: on
@@ -258,23 +262,24 @@ static void nmi_cpu_shutdown(void *dummy
*/
v = apic_read(APIC_LVTERR);
apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
- apic_write(APIC_LVTPC, saved_lvtpc[cpu]);
+ apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu));
apic_write(APIC_LVTERR, v);
nmi_restore_registers(msrs);
}
static void nmi_shutdown(void)
{
+ struct op_msrs *msrs = &__get_cpu_var(cpu_msrs);
nmi_enabled = 0;
on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
unregister_die_notifier(&profile_exceptions_nb);
- model->shutdown(cpu_msrs);
+ model->shutdown(msrs);
free_msrs();
}
static void nmi_cpu_start(void *dummy)
{
- struct op_msrs const *msrs = &cpu_msrs[smp_processor_id()];
+ struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
model->start(msrs);
}
@@ -286,7 +291,7 @@ static int nmi_start(void)
static void nmi_cpu_stop(void *dummy)
{
- struct op_msrs const *msrs = &cpu_msrs[smp_processor_id()];
+ struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
model->stop(msrs);
}
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 10/10] sched: Remove fixed NR_CPUS sized arrays in kernel_sched.c
2008-03-25 2:19 [PATCH 00/10] NR_CPUS: third reduction of NR_CPUS memory usage Mike Travis
` (8 preceding siblings ...)
2008-03-25 2:20 ` [PATCH 09/10] x86: oprofile: remove NR_CPUS arrays in arch/x86/oprofile/nmi_int.c Mike Travis
@ 2008-03-25 2:20 ` Mike Travis
9 siblings, 0 replies; 13+ messages in thread
From: Mike Travis @ 2008-03-25 2:20 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-mm, linux-kernel, Ingo Molnar
[-- Attachment #1: nr_cpus-in-kernel_sched --]
[-- Type: text/plain, Size: 7844 bytes --]
Change fixed size arrays to per_cpu variables or dynamically allocated
arrays in sched_init() and sched_init_smp().
(1) static struct sched_entity *init_sched_entity_p[NR_CPUS];
(1) static struct cfs_rq *init_cfs_rq_p[NR_CPUS];
(1) static struct sched_rt_entity *init_sched_rt_entity_p[NR_CPUS];
(1) static struct rt_rq *init_rt_rq_p[NR_CPUS];
static struct sched_group **sched_group_nodes_bycpu[NR_CPUS];
char str[NR_CPUS];
int ints[NR_CPUS], i;
(1 - these arrays are allocated via alloc_bootmem_low())
Also in sched_create_group() we allocate new arrays based on nr_cpu_ids.
Based on linux-2.6.25-rc5-mm1
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Mike Travis <travis@sgi.com>
---
kernel/sched.c | 92 +++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 63 insertions(+), 29 deletions(-)
--- linux-2.6.25-rc5.orig/kernel/sched.c
+++ linux-2.6.25-rc5/kernel/sched.c
@@ -67,6 +67,7 @@
#include <linux/pagemap.h>
#include <linux/hrtimer.h>
#include <linux/tick.h>
+#include <linux/bootmem.h>
#include <asm/tlb.h>
#include <asm/irq_regs.h>
@@ -194,17 +195,11 @@ struct task_group {
static DEFINE_PER_CPU(struct sched_entity, init_sched_entity);
/* Default task group's cfs_rq on each cpu */
static DEFINE_PER_CPU(struct cfs_rq, init_cfs_rq) ____cacheline_aligned_in_smp;
-
-static struct sched_entity *init_sched_entity_p[NR_CPUS];
-static struct cfs_rq *init_cfs_rq_p[NR_CPUS];
#endif
#ifdef CONFIG_RT_GROUP_SCHED
static DEFINE_PER_CPU(struct sched_rt_entity, init_sched_rt_entity);
static DEFINE_PER_CPU(struct rt_rq, init_rt_rq) ____cacheline_aligned_in_smp;
-
-static struct sched_rt_entity *init_sched_rt_entity_p[NR_CPUS];
-static struct rt_rq *init_rt_rq_p[NR_CPUS];
#endif
/* task_group_lock serializes add/remove of task groups and also changes to
@@ -228,17 +223,7 @@ static int init_task_group_load = INIT_T
/* Default task group.
* Every task in system belong to this group at bootup.
*/
-struct task_group init_task_group = {
-#ifdef CONFIG_FAIR_GROUP_SCHED
- .se = init_sched_entity_p,
- .cfs_rq = init_cfs_rq_p,
-#endif
-
-#ifdef CONFIG_RT_GROUP_SCHED
- .rt_se = init_sched_rt_entity_p,
- .rt_rq = init_rt_rq_p,
-#endif
-};
+struct task_group init_task_group;
/* return group to which a task belongs */
static inline struct task_group *task_group(struct task_struct *p)
@@ -3587,7 +3572,7 @@ static inline void trigger_load_balance(
*/
int ilb = first_cpu(nohz.cpu_mask);
- if (ilb != NR_CPUS)
+ if (ilb < nr_cpu_ids)
resched_cpu(ilb);
}
}
@@ -5544,11 +5529,11 @@ static void move_task_off_dead_cpu(int d
dest_cpu = any_online_cpu(mask);
/* On any allowed CPU? */
- if (dest_cpu == NR_CPUS)
+ if (dest_cpu >= nr_cpu_ids)
dest_cpu = any_online_cpu(p->cpus_allowed);
/* No more Mr. Nice Guy. */
- if (dest_cpu == NR_CPUS) {
+ if (dest_cpu >= nr_cpu_ids) {
cpumask_t cpus_allowed = cpuset_cpus_allowed_locked(p);
/*
* Try to stay on the same cpuset, where the
@@ -6001,9 +5986,16 @@ static int sched_domain_debug_one(struct
{
struct sched_group *group = sd->groups;
cpumask_t groupmask;
- char str[NR_CPUS];
+ int len = cpumask_scnprintf_len(nr_cpu_ids);
+ char *str = kmalloc(len, GFP_KERNEL);
+ int ret = 0;
+
+ if (!str) {
+ printk(KERN_DEBUG "Cannot load-balance (no memory)\n");
+ return -1;
+ }
- cpumask_scnprintf(str, NR_CPUS, sd->span);
+ cpumask_scnprintf(str, len, sd->span);
cpus_clear(groupmask);
printk(KERN_DEBUG "%*s domain %d: ", level, "", level);
@@ -6013,6 +6005,7 @@ static int sched_domain_debug_one(struct
if (sd->parent)
printk(KERN_ERR "ERROR: !SD_LOAD_BALANCE domain"
" has parent");
+ kfree(str);
return -1;
}
@@ -6056,7 +6049,7 @@ static int sched_domain_debug_one(struct
cpus_or(groupmask, groupmask, group->cpumask);
- cpumask_scnprintf(str, NR_CPUS, group->cpumask);
+ cpumask_scnprintf(str, len, group->cpumask);
printk(KERN_CONT " %s", str);
group = group->next;
@@ -6069,6 +6062,8 @@ static int sched_domain_debug_one(struct
if (sd->parent && !cpus_subset(groupmask, sd->parent->span))
printk(KERN_ERR "ERROR: parent span is not a superset "
"of domain->span\n");
+
+ kfree(str);
return 0;
}
@@ -6250,7 +6245,7 @@ cpu_attach_domain(struct sched_domain *s
/*
* init_sched_build_groups takes the cpumask we wish to span, and a pointer
* to a function which identifies what group(along with sched group) a CPU
- * belongs to. The return value of group_fn must be a >= 0 and < NR_CPUS
+ * belongs to. The return value of group_fn must be a >= 0 and < nr_cpu_ids
* (due to the fact that we keep track of groups covered with a cpumask_t).
*
* init_sched_build_groups will build a circular linked list of the groups
@@ -6448,7 +6443,7 @@ cpu_to_phys_group(int cpu, const cpumask
* gets dynamically allocated.
*/
static DEFINE_PER_CPU(struct sched_domain, node_domains);
-static struct sched_group **sched_group_nodes_bycpu[NR_CPUS];
+static struct sched_group ***sched_group_nodes_bycpu;
static DEFINE_PER_CPU(struct sched_domain, allnodes_domains);
static DEFINE_PER_CPU(struct sched_group, sched_group_allnodes);
@@ -7086,6 +7081,11 @@ void __init sched_init_smp(void)
{
cpumask_t non_isolated_cpus;
+#if defined(CONFIG_NUMA)
+ sched_group_nodes_bycpu = kzalloc(nr_cpu_ids * sizeof(void **),
+ GFP_KERNEL);
+ BUG_ON(sched_group_nodes_bycpu == NULL);
+#endif
get_online_cpus();
arch_init_sched_domains(&cpu_online_map);
non_isolated_cpus = cpu_possible_map;
@@ -7103,6 +7103,11 @@ void __init sched_init_smp(void)
#else
void __init sched_init_smp(void)
{
+#if defined(CONFIG_NUMA)
+ sched_group_nodes_bycpu = kzalloc(nr_cpu_ids * sizeof(void **),
+ GFP_KERNEL);
+ BUG_ON(sched_group_nodes_bycpu == NULL);
+#endif
sched_init_granularity();
}
#endif /* CONFIG_SMP */
@@ -7196,6 +7201,35 @@ static void init_tg_rt_entry(struct rq *
void __init sched_init(void)
{
int i, j;
+ unsigned long alloc_size = 0, ptr;
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ alloc_size += 2 * nr_cpu_ids * sizeof(void **);
+#endif
+#ifdef CONFIG_RT_GROUP_SCHED
+ alloc_size += 2 * nr_cpu_ids * sizeof(void **);
+#endif
+ /*
+ * As sched_init() is called before page_alloc is setup,
+ * we use alloc_bootmem().
+ */
+ if (alloc_size) {
+ ptr = (unsigned long)alloc_bootmem_low(alloc_size);
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ init_task_group.se = (struct sched_entity **)ptr;
+ ptr += nr_cpu_ids * sizeof(void **);
+
+ init_task_group.cfs_rq = (struct cfs_rq **)ptr;
+ ptr += nr_cpu_ids * sizeof(void **);
+#endif
+#ifdef CONFIG_RT_GROUP_SCHED
+ init_task_group.rt_se = (struct sched_rt_entity **)ptr;
+ ptr += nr_cpu_ids * sizeof(void **);
+
+ init_task_group.rt_rq = (struct rt_rq **)ptr;
+#endif
+ }
#ifdef CONFIG_SMP
init_defrootdomain();
@@ -7442,10 +7476,10 @@ static int alloc_fair_sched_group(struct
struct rq *rq;
int i;
- tg->cfs_rq = kzalloc(sizeof(cfs_rq) * NR_CPUS, GFP_KERNEL);
+ tg->cfs_rq = kzalloc(sizeof(cfs_rq) * nr_cpu_ids, GFP_KERNEL);
if (!tg->cfs_rq)
goto err;
- tg->se = kzalloc(sizeof(se) * NR_CPUS, GFP_KERNEL);
+ tg->se = kzalloc(sizeof(se) * nr_cpu_ids, GFP_KERNEL);
if (!tg->se)
goto err;
@@ -7525,10 +7559,10 @@ static int alloc_rt_sched_group(struct t
struct rq *rq;
int i;
- tg->rt_rq = kzalloc(sizeof(rt_rq) * NR_CPUS, GFP_KERNEL);
+ tg->rt_rq = kzalloc(sizeof(rt_rq) * nr_cpu_ids, GFP_KERNEL);
if (!tg->rt_rq)
goto err;
- tg->rt_se = kzalloc(sizeof(rt_se) * NR_CPUS, GFP_KERNEL);
+ tg->rt_se = kzalloc(sizeof(rt_se) * nr_cpu_ids, GFP_KERNEL);
if (!tg->rt_se)
goto err;
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 13+ messages in thread