diff options
author | Mike Travis <travis@sgi.com> | 2009-01-11 01:24:06 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-11 13:13:35 -0500 |
commit | 0fa0ebbf15addc1be8f73325d809c8547a9de304 (patch) | |
tree | cd995419a3eb84d3e18e92ff205af86a7a4ed66d | |
parent | e2f4d06545ec1f29b0e838ee34cbf3500ea5b9a4 (diff) |
irq: allocate irq_desc_ptrs array based on nr_irqs
Impact: allocate irq_desc_ptrs in preparation for making it variable-sized.
This addresses this memory usage bump when NR_CPUS bumped from 128 to 4096:
34816 +229376 264192 +658% irq_desc_ptrs(.data.read_mostly)
The patch is split into two parts, the first simply allocates the
irq_desc_ptrs array. Then next will deal with making it variable.
This is only when CONFIG_SPARSE_IRQS=y.
Signed-off-by: Mike Travis <travis@sgi.com>
-rw-r--r-- | kernel/irq/handle.c | 11 | ||||
-rw-r--r-- | kernel/irq/internals.h | 7 |
2 files changed, 16 insertions, 2 deletions
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index fd1ef16252f4..d0b8f7e72790 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/kernel_stat.h> | 17 | #include <linux/kernel_stat.h> |
18 | #include <linux/rculist.h> | 18 | #include <linux/rculist.h> |
19 | #include <linux/hash.h> | 19 | #include <linux/hash.h> |
20 | #include <linux/bootmem.h> | ||
20 | 21 | ||
21 | #include "internals.h" | 22 | #include "internals.h" |
22 | 23 | ||
@@ -110,7 +111,7 @@ static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu) | |||
110 | */ | 111 | */ |
111 | DEFINE_SPINLOCK(sparse_irq_lock); | 112 | DEFINE_SPINLOCK(sparse_irq_lock); |
112 | 113 | ||
113 | struct irq_desc *irq_desc_ptrs[NR_IRQS] __read_mostly; | 114 | struct irq_desc **irq_desc_ptrs __read_mostly; |
114 | 115 | ||
115 | static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = { | 116 | static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = { |
116 | [0 ... NR_IRQS_LEGACY-1] = { | 117 | [0 ... NR_IRQS_LEGACY-1] = { |
@@ -137,6 +138,9 @@ int __init early_irq_init(void) | |||
137 | desc = irq_desc_legacy; | 138 | desc = irq_desc_legacy; |
138 | legacy_count = ARRAY_SIZE(irq_desc_legacy); | 139 | legacy_count = ARRAY_SIZE(irq_desc_legacy); |
139 | 140 | ||
141 | /* allocate irq_desc_ptrs array based on nr_irqs */ | ||
142 | irq_desc_ptrs = alloc_bootmem(nr_irqs * sizeof(void *)); | ||
143 | |||
140 | for (i = 0; i < legacy_count; i++) { | 144 | for (i = 0; i < legacy_count; i++) { |
141 | desc[i].irq = i; | 145 | desc[i].irq = i; |
142 | desc[i].kstat_irqs = kstat_irqs_legacy[i]; | 146 | desc[i].kstat_irqs = kstat_irqs_legacy[i]; |
@@ -153,7 +157,10 @@ int __init early_irq_init(void) | |||
153 | 157 | ||
154 | struct irq_desc *irq_to_desc(unsigned int irq) | 158 | struct irq_desc *irq_to_desc(unsigned int irq) |
155 | { | 159 | { |
156 | return (irq < nr_irqs) ? irq_desc_ptrs[irq] : NULL; | 160 | if (irq_desc_ptrs && irq < nr_irqs) |
161 | return irq_desc_ptrs[irq]; | ||
162 | |||
163 | return NULL; | ||
157 | } | 164 | } |
158 | 165 | ||
159 | struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu) | 166 | struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu) |
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index e6d0a43cc125..40416a81a0f5 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h | |||
@@ -16,7 +16,14 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | |||
16 | extern struct lock_class_key irq_desc_lock_class; | 16 | extern struct lock_class_key irq_desc_lock_class; |
17 | extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr); | 17 | extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr); |
18 | extern spinlock_t sparse_irq_lock; | 18 | extern spinlock_t sparse_irq_lock; |
19 | |||
20 | #ifdef CONFIG_SPARSE_IRQ | ||
21 | /* irq_desc_ptrs allocated at boot time */ | ||
22 | extern struct irq_desc **irq_desc_ptrs; | ||
23 | #else | ||
24 | /* irq_desc_ptrs is a fixed size array */ | ||
19 | extern struct irq_desc *irq_desc_ptrs[NR_IRQS]; | 25 | extern struct irq_desc *irq_desc_ptrs[NR_IRQS]; |
26 | #endif | ||
20 | 27 | ||
21 | #ifdef CONFIG_PROC_FS | 28 | #ifdef CONFIG_PROC_FS |
22 | extern void register_irq_proc(unsigned int irq, struct irq_desc *desc); | 29 | extern void register_irq_proc(unsigned int irq, struct irq_desc *desc); |