diff options
author | Yinghai Lu <yinghai@kernel.org> | 2008-12-05 21:58:31 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-08 08:31:51 -0500 |
commit | 0b8f1efad30bd58f89961b82dfe68b9edf8fd2ac (patch) | |
tree | 239251bad791fd60af8c0f2ba365b7188395c83f /drivers/xen/events.c | |
parent | 218d11a8b071b23b76c484fd5f72a4fe3306801e (diff) |
sparse irq_desc[] array: core kernel and x86 changes
Impact: new feature
Problem on distro kernels: irq_desc[NR_IRQS] takes megabytes of RAM with
NR_CPUS set to large values. The goal is to be able to scale up to much
larger NR_IRQS value without impacting the (important) common case.
To solve this, we generalize irq_desc[NR_IRQS] to an (optional) array of
irq_desc pointers.
When CONFIG_SPARSE_IRQ=y is used, we use kzalloc_node to get irq_desc,
this also makes the IRQ descriptors NUMA-local (to the site that calls
request_irq()).
This gets rid of the irq_cfg[] static array on x86 as well: irq_cfg now
uses desc->chip_data for x86 to store irq_cfg.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/xen/events.c')
-rw-r--r-- | drivers/xen/events.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 1e3b934a4cf7..2924faa7f6c4 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -141,8 +141,12 @@ static void init_evtchn_cpu_bindings(void) | |||
141 | int i; | 141 | int i; |
142 | 142 | ||
143 | /* By default all event channels notify CPU#0. */ | 143 | /* By default all event channels notify CPU#0. */ |
144 | for_each_irq_desc(i, desc) | 144 | for_each_irq_desc(i, desc) { |
145 | if (!desc) | ||
146 | continue; | ||
147 | |||
145 | desc->affinity = cpumask_of_cpu(0); | 148 | desc->affinity = cpumask_of_cpu(0); |
149 | } | ||
146 | #endif | 150 | #endif |
147 | 151 | ||
148 | memset(cpu_evtchn, 0, sizeof(cpu_evtchn)); | 152 | memset(cpu_evtchn, 0, sizeof(cpu_evtchn)); |
@@ -231,7 +235,7 @@ static int find_unbound_irq(void) | |||
231 | int irq; | 235 | int irq; |
232 | 236 | ||
233 | /* Only allocate from dynirq range */ | 237 | /* Only allocate from dynirq range */ |
234 | for_each_irq_nr(irq) | 238 | for (irq = 0; irq < nr_irqs; irq++) |
235 | if (irq_bindcount[irq] == 0) | 239 | if (irq_bindcount[irq] == 0) |
236 | break; | 240 | break; |
237 | 241 | ||
@@ -792,7 +796,7 @@ void xen_irq_resume(void) | |||
792 | mask_evtchn(evtchn); | 796 | mask_evtchn(evtchn); |
793 | 797 | ||
794 | /* No IRQ <-> event-channel mappings. */ | 798 | /* No IRQ <-> event-channel mappings. */ |
795 | for_each_irq_nr(irq) | 799 | for (irq = 0; irq < nr_irqs; irq++) |
796 | irq_info[irq].evtchn = 0; /* zap event-channel binding */ | 800 | irq_info[irq].evtchn = 0; /* zap event-channel binding */ |
797 | 801 | ||
798 | for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) | 802 | for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) |
@@ -824,7 +828,7 @@ void __init xen_init_IRQ(void) | |||
824 | mask_evtchn(i); | 828 | mask_evtchn(i); |
825 | 829 | ||
826 | /* Dynamic IRQ space is currently unbound. Zero the refcnts. */ | 830 | /* Dynamic IRQ space is currently unbound. Zero the refcnts. */ |
827 | for_each_irq_nr(i) | 831 | for (i = 0; i < nr_irqs; i++) |
828 | irq_bindcount[i] = 0; | 832 | irq_bindcount[i] = 0; |
829 | 833 | ||
830 | irq_ctx_init(smp_processor_id()); | 834 | irq_ctx_init(smp_processor_id()); |