Please check dyn_array support for x86
v3: split changing to nr_irqs to small patches
fix checkpatch error
reorder the patch sequence to make dyn_array support go at first
so could use that with arrays other than NR_IRQS
v4: add CONFIG_HAVE_SPARSE_IRQ with list to use condensed irq_desc array
so could use 32 init, and init more if needed.
x86 32bit: have CONFIG_HAVE_DYN_ARRAY
x86 64bit: have CONFIG_HAVE_DYN_ARRAY and CONFIG_HAVE_SPARSE_IRQ
v5: apply alan cox patch with NR_IRQS for serial at first
seperate irq_descX with irq_descX_free, so could use -1U as valid irq
expand /proc/interrupts to process > nr_irqs
hook irq_2_iommu to irq_desc
more other arch irq_desc[] to irq_desc(), and kstat_cpu().irqs[] to kstat_irqs_cpu..
based on tip/master
to do:
so dyn irq_desc is done, and ready to:
make create_irq to get irq according to bus/dev/func/vector
Thanks
Yinghai Lu
--
From: Alan Cox <alan@redhat.com>
Works on my test box with a quick test.
From: Alan Cox <alan@redhat.com>
Signed-off-by: Alan Cox <alan@redhat.com>
---
drivers/serial/68328serial.c | 11 +-----
drivers/serial/8250.c | 73 +++++++++++++++++++++++++++++++++--------
2 files changed, 60 insertions(+), 24 deletions(-)
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 381b12a..277b78d 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -66,7 +66,6 @@
#endif
static struct m68k_serial m68k_soft[NR_PORTS];
-struct m68k_serial *IRQ_ports[NR_IRQS];
static unsigned int uart_irqs[NR_PORTS] = UART_IRQ_DEFNS;
@@ -375,15 +374,11 @@ clear_and_return:
*/
irqreturn_t rs_interrupt(int irq, void *dev_id)
{
- struct m68k_serial * info;
+ struct m68k_serial * info = dev_id;
m68328_uart *uart;
unsigned short rx;
unsigned short tx;
- info = IRQ_ports[irq];
- if(!info)
- return IRQ_NONE;
-
uart = &uart_addr[info->line];
rx = uart->urx.w;
@@ -1383,8 +1378,6 @@ rs68328_init(void)
info->port, info->irq);
printk(" is a builtin MC68328 UART\n");
- IRQ_ports[info->irq] = info; /* waste of space */
-
#ifdef CONFIG_M68VZ328
if (i > 0 )
PJSEL &= 0xCF; /* PSW enable second port output */
@@ -1393,7 +1386,7 @@ rs68328_init(void)
if (request_irq(uart_irqs[i],
rs_interrupt,
IRQF_DISABLED,
- "M68328_UART", NULL))
+ "M68328_UART", info))
panic("Unable to attach 68328 serial interrupt\n");
}
local_irq_restore(flags);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 3a4d677..71c8e68 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -145,11 +145,15 @@ struct uart_8250_port {
};
struct irq_info {
- spinlock_t lock;
+ struct hlist_node node;
+ int irq;
+ spinlock_t lock; /* Protects list not the hash */
struct list_head *head;
};
-static struct ...to prepare to use dyn_array support etc.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/mm/init_32.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 4974e97..b5c1751 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -65,6 +65,7 @@ static unsigned long __meminitdata table_end;
static unsigned long __meminitdata table_top;
static int __initdata after_init_bootmem;
+int after_bootmem;
static __init void *alloc_low_page(unsigned long *phys)
{
@@ -924,6 +925,8 @@ void __init mem_init(void)
set_highmem_pages_init();
+ after_bootmem = 1;
+
codesize = (unsigned long) &_etext - (unsigned long) &_text;
datasize = (unsigned long) &_edata - (unsigned long) &_etext;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
--
1.5.4.5
--
no user Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- include/asm-x86/mach-generic/irq_vectors_limits.h | 14 -------------- include/asm-x86/summit/irq_vectors_limits.h | 14 -------------- 2 files changed, 0 insertions(+), 28 deletions(-) delete mode 100644 include/asm-x86/mach-generic/irq_vectors_limits.h delete mode 100644 include/asm-x86/summit/irq_vectors_limits.h diff --git a/include/asm-x86/mach-generic/irq_vectors_limits.h b/include/asm-x86/mach-generic/irq_vectors_limits.h deleted file mode 100644 index f7870e1..0000000 --- a/include/asm-x86/mach-generic/irq_vectors_limits.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H -#define ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H - -/* - * For Summit or generic (i.e. installer) kernels, we have lots of I/O APICs, - * even with uni-proc kernels, so use a big array. - * - * This value should be the same in both the generic and summit subarches. - * Change one, change 'em both. - */ -#define NR_IRQS 224 -#define NR_IRQ_VECTORS 1024 - -#endif /* ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H */ diff --git a/include/asm-x86/summit/irq_vectors_limits.h b/include/asm-x86/summit/irq_vectors_limits.h deleted file mode 100644 index 890ce3f..0000000 --- a/include/asm-x86/summit/irq_vectors_limits.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _ASM_IRQ_VECTORS_LIMITS_H -#define _ASM_IRQ_VECTORS_LIMITS_H - -/* - * For Summit or generic (i.e. installer) kernels, we have lots of I/O APICs, - * even with uni-proc kernels, so use a big array. - * - * This value should be the same in both the generic and summit subarches. - * Change one, change 'em both. - */ -#define NR_IRQS 224 -#define NR_IRQ_VECTORS 1024 - -#endif /* _ASM_IRQ_VECTORS_LIMITS_H */ -- 1.5.4.5 --
could have crazy big arrays and allocate them in bootmem at init stage.
also also to allocate array according to size we need to use to avoid wasting
memory
use CONFIG_HAVE_DYN_ARRAY to enable it or not
usage:
|static struct irq_desc irq_desc_init __initdata = {
| .status = IRQ_DISABLED,
| .chip = &no_irq_chip,
| .handle_irq = handle_bad_irq,
| .depth = 1,
| .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
|#ifdef CONFIG_SMP
| .affinity = CPU_MASK_ALL
|#endif
|};
|
|static void __init init_work(void *data)
|{
| struct dyn_array *da = data;
| struct irq_desc *desc;
| int i;
|
| desc = *da->name;
|
| for (i = 0; i < *da->nr; i++)
| memcpy(&desc[i], &irq_desc_init, sizeof(struct irq_desc));
|}
|
|struct irq_desc *irq_desc;
|DEFINE_DYN_ARRAY(irq_desc, sizeof(struct irq_desc), nr_irqs, PAGE_SIZE, init_work);
after pre_alloc_dyn_array() after setup_arch(), that array is ready to use
in this way could replace irq_desc[NR_IRQS] array with dyn_array irq_desc[nr_irqs]
v2: remove _nopanic in pre_alloc_dyn_array()
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
include/asm-generic/vmlinux.lds.h | 7 +++++++
include/linux/init.h | 23 +++++++++++++++++++++++
init/main.c | 24 ++++++++++++++++++++++++
3 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index a44ec7a..1c3daac 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -214,6 +214,13 @@
* All archs are supposed to use RO_DATA() */
#define RODATA RO_DATA(4096)
+#define DYN_ARRAY_INIT(align) \
+ . = ALIGN((align)); \
+ .dyn_array.init : AT(ADDR(.dyn_array.init) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__dyn_array_start) = .; \
+ *(.dyn_array.init) \
+ VMLINUX_SYMBOL(__dyn_array_end) = .; \
+ }
#define SECURITY_INIT \
...could make array in per_cpu is allocated dynamically too
usage:
| /* in .h */
|struct kernel_stat {
| struct cpu_usage_stat cpustat;
| unsigned int *irqs;
|};
|
| /* in .c */
|DEFINE_PER_CPU(struct kernel_stat, kstat);
|
|DEFINE_PER_CPU_DYN_ARRAY_ADDR(per_cpu__kstat_irqs, per_cpu__kstat.irqs, sizeof(unsigned int), nr_irqs, sizeof(unsigned long), NULL);
after setup_percpu()/per_cpu_alloc_dyn_array(), that dyn_array in per_cpu area is ready to use
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/setup_percpu.c | 7 +++-
include/asm-generic/vmlinux.lds.h | 6 +++
include/linux/init.h | 27 ++++++++++++++--
init/main.c | 63 +++++++++++++++++++++++++++++++++++-
4 files changed, 96 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 0e67f72..13ba7a8 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -140,7 +140,7 @@ static void __init setup_cpu_pda_map(void)
*/
void __init setup_per_cpu_areas(void)
{
- ssize_t size = PERCPU_ENOUGH_ROOM;
+ ssize_t size, old_size;
char *ptr;
int cpu;
@@ -148,7 +148,8 @@ void __init setup_per_cpu_areas(void)
setup_cpu_pda_map();
/* Copy section for each CPU (we discard the original) */
- size = PERCPU_ENOUGH_ROOM;
+ old_size = PERCPU_ENOUGH_ROOM;
+ size = old_size + per_cpu_dyn_array_size();
printk(KERN_INFO "PERCPU: Allocating %zd bytes of per cpu data\n",
size);
@@ -176,6 +177,8 @@ void __init setup_per_cpu_areas(void)
per_cpu_offset(cpu) = ptr - __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+ per_cpu_alloc_dyn_array(cpu, ptr + old_size);
+
}
printk(KERN_DEBUG "NR_CPUS: %d, nr_cpu_ids: %d, nr_node_ids %d\n",
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 1c3daac..e76244a 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ ...so could spare some memory with small alignment in bootmem
also tighten the alignment checking..., and make print out less debug info
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/setup_percpu.c | 16 +++++++---
include/linux/init.h | 2 +-
init/main.c | 65 ++++++++++++++++++++++++++++++---------
3 files changed, 62 insertions(+), 21 deletions(-)
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 13ba7a8..2b7dab6 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -140,26 +140,31 @@ static void __init setup_cpu_pda_map(void)
*/
void __init setup_per_cpu_areas(void)
{
- ssize_t size, old_size;
+ ssize_t size, old_size, da_size;
char *ptr;
int cpu;
+ unsigned long align = 1;
/* Setup cpu_pda map */
setup_cpu_pda_map();
/* Copy section for each CPU (we discard the original) */
old_size = PERCPU_ENOUGH_ROOM;
- size = old_size + per_cpu_dyn_array_size();
+ da_size = per_cpu_dyn_array_size(&align);
+ align = max_t(unsigned long, PAGE_SIZE, align);
+ size = roundup(old_size + da_size, align);
printk(KERN_INFO "PERCPU: Allocating %zd bytes of per cpu data\n",
size);
for_each_possible_cpu(cpu) {
#ifndef CONFIG_NEED_MULTIPLE_NODES
- ptr = alloc_bootmem_pages(size);
+ ptr = __alloc_bootmem(size, align,
+ __pa(MAX_DMA_ADDRESS));
#else
int node = early_cpu_to_node(cpu);
if (!node_online(node) || !NODE_DATA(node)) {
- ptr = alloc_bootmem_pages(size);
+ ptr = __alloc_bootmem(size, align,
+ __pa(MAX_DMA_ADDRESS));
printk(KERN_INFO
"cpu %d has no node %d or node-local memory\n",
cpu, node);
@@ -168,7 +173,8 @@ void __init setup_per_cpu_areas(void)
cpu, __pa(ptr));
}
else {
- ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
+ ptr = __alloc_bootmem_node(NODE_DATA(node), size, align,
+ __pa(MAX_DMA_ADDRESS));
if (ptr)
...Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/Kconfig | 2 ++
arch/x86/Kconfig | 1 +
arch/x86/kernel/vmlinux_32.lds.S | 1 +
arch/x86/kernel/vmlinux_64.lds.S | 3 +++
4 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index 0267bab..c1f9feb 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -103,3 +103,5 @@ config HAVE_CLK
The <linux/clk.h> calls support software clock gating and
thus are a key power management tool on many systems.
+config HAVE_DYN_ARRAY
+ def_bool n
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bd30e8b..d30b101 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -33,6 +33,7 @@ config X86
select HAVE_ARCH_TRACEHOOK
select HAVE_GENERIC_DMA_COHERENT if X86_32
select HAVE_EFFICIENT_UNALIGNED_ACCESS
+ select HAVE_DYN_ARRAY
config ARCH_DEFCONFIG
string
diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S
index 248a575..20b835a 100644
--- a/arch/x86/kernel/vmlinux_32.lds.S
+++ b/arch/x86/kernel/vmlinux_32.lds.S
@@ -145,6 +145,7 @@ SECTIONS
*(.x86cpuvendor.init)
__x86cpuvendor_end = .;
}
+ DYN_ARRAY_INIT(8)
SECURITY_INIT
. = ALIGN(4);
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index 63e5c1a..5b9cc10 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -174,6 +174,9 @@ SECTIONS
*(.x86cpuvendor.init)
}
__x86cpuvendor_end = .;
+
+ DYN_ARRAY_INIT(8)
+
SECURITY_INIT
. = ALIGN(8);
--
1.5.4.5
--
and at this point it is equal NR_IRQS
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
include/linux/irq.h | 2 ++
kernel/irq/autoprobe.c | 10 +++++-----
kernel/irq/chip.c | 20 ++++++++++----------
kernel/irq/handle.c | 3 ++-
kernel/irq/manage.c | 16 ++++++++--------
kernel/irq/proc.c | 2 +-
kernel/irq/resend.c | 4 ++--
kernel/irq/spurious.c | 4 ++--
8 files changed, 32 insertions(+), 29 deletions(-)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 1d73d1a..bd69d90 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -24,6 +24,8 @@
#include <asm/ptrace.h>
#include <asm/irq_regs.h>
+extern int nr_irqs;
+
struct irq_desc;
typedef void (*irq_flow_handler_t)(unsigned int irq,
struct irq_desc *desc);
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 533068c..c689e98 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -38,7 +38,7 @@ unsigned long probe_irq_on(void)
* something may have generated an irq long ago and we want to
* flush such a longstanding irq before considering it as spurious.
*/
- for (i = NR_IRQS-1; i > 0; i--) {
+ for (i = nr_irqs-1; i > 0; i--) {
desc = irq_desc + i;
spin_lock_irq(&desc->lock);
@@ -68,7 +68,7 @@ unsigned long probe_irq_on(void)
* (we must startup again here because if a longstanding irq
* happened in the previous stage, it may have masked itself)
*/
- for (i = NR_IRQS-1; i > 0; i--) {
+ for (i = nr_irqs-1; i > 0; i--) {
desc = irq_desc + i;
spin_lock_irq(&desc->lock);
@@ -89,7 +89,7 @@ unsigned long probe_irq_on(void)
* Now filter out any obviously spurious interrupts
*/
mask = 0;
- for (i = 0; i < NR_IRQS; i++) {
+ for (i = 0; i < nr_irqs; i++) {
unsigned int status;
desc = irq_desc + i;
@@ -130,7 +130,7 @@ unsigned int probe_irq_mask(unsigned long val)
int i;
mask = 0;
- for (i = 0; i < NR_IRQS; i++) {
+ for (i = 0; i < nr_irqs; i++) ...also add first_free_entry and pin_map_size
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/io_apic_32.c | 26 ++++++++++++++------------
arch/x86/kernel/io_apic_64.c | 33 +++++++++++++++++----------------
arch/x86/kernel/irq_32.c | 8 ++++----
arch/x86/kernel/irq_64.c | 8 ++++----
arch/x86/kernel/irqinit_32.c | 2 +-
arch/x86/kernel/irqinit_64.c | 2 +-
include/asm-x86/irq.h | 3 +++
7 files changed, 44 insertions(+), 38 deletions(-)
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index 7f0d88c..d5953ff 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -70,6 +70,7 @@ int timer_through_8259 __initdata;
*/
int sis_apic_bug = -1;
+int first_free_entry = NR_IRQS;
/*
* # of IRQ routing registers
*/
@@ -100,6 +101,8 @@ static int disable_timer_pin_1 __initdata;
#define MAX_PLUS_SHARED_IRQS NR_IRQS
#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
+int pin_map_size = PIN_MAP_SIZE;
+
/*
* This is performance-critical, we want to do it O(1)
*
@@ -213,7 +216,6 @@ static void ioapic_mask_entry(int apic, int pin)
*/
static void add_pin_to_irq(unsigned int irq, int apic, int pin)
{
- static int first_free_entry = NR_IRQS;
struct irq_pin_list *entry = irq_2_pin + irq;
while (entry->next)
@@ -222,7 +224,7 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin)
if (entry->pin != -1) {
entry->next = first_free_entry;
entry = irq_2_pin + entry->next;
- if (++first_free_entry >= PIN_MAP_SIZE)
+ if (++first_free_entry >= pin_map_size)
panic("io_apic.c: whoops");
}
entry->apic = apic;
@@ -457,7 +459,7 @@ static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold)
int i, j;
for_each_online_cpu(i) {
- for (j = 0; j < NR_IRQS; j++) {
+ for (j = 0; j < nr_irqs; j++) {
if (!irq_desc[j].action)
continue;
/* Is it a significant load ? */
@@ -492,7 +494,7 @@ ...Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
drivers/char/hpet.c | 2 +-
drivers/char/random.c | 4 ++--
drivers/char/vr41xx_giu.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 2908a0e..8d562ae 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -219,7 +219,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ;
irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) {
- if (irq >= NR_IRQS) {
+ if (irq >= nr_irqs) {
irq = HPET_MAX_IRQ;
break;
}
diff --git a/drivers/char/random.c b/drivers/char/random.c
index e0d0e37..fdbdcfc 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -647,7 +647,7 @@ EXPORT_SYMBOL_GPL(add_input_randomness);
void add_interrupt_randomness(int irq)
{
- if (irq >= NR_IRQS || irq_timer_state[irq] == NULL)
+ if (irq >= nr_irqs || irq_timer_state[irq] == NULL)
return;
DEBUG_ENT("irq event %d\n", irq);
@@ -911,7 +911,7 @@ void rand_initialize_irq(int irq)
{
struct timer_rand_state *state;
- if (irq >= NR_IRQS || irq_timer_state[irq])
+ if (irq >= nr_irqs || irq_timer_state[irq])
return;
/*
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index ffe9b4e..54c8372 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -641,7 +641,7 @@ static int __devinit giu_probe(struct platform_device *dev)
}
irq = platform_get_irq(dev, 0);
- if (irq < 0 || irq >= NR_IRQS)
+ if (irq < 0 || irq >= nr_irqs)
return -EBUSY;
return cascade_irq(irq, giu_get_irq);
--
1.5.4.5
--
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
drivers/net/3c59x.c | 4 ++--
drivers/net/hamradio/baycom_ser_fdx.c | 4 ++--
drivers/net/hamradio/scc.c | 6 +++---
drivers/net/wan/sbni.c | 2 +-
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 8db4e6b..7449a1c 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -90,7 +90,7 @@ static int vortex_debug = 1;
#include <linux/eisa.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
-#include <asm/irq.h> /* For NR_IRQS only. */
+#include <asm/irq.h> /* For nr_irqs only. */
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -1221,7 +1221,7 @@ static int __devinit vortex_probe1(struct device *gendev,
if (print_info)
printk(", IRQ %d\n", dev->irq);
/* Tell them about an invalid IRQ. */
- if (dev->irq <= 0 || dev->irq >= NR_IRQS)
+ if (dev->irq <= 0 || dev->irq >= nr_irqs)
printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n",
dev->irq);
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
index 17ac697..b6a816e 100644
--- a/drivers/net/hamradio/baycom_ser_fdx.c
+++ b/drivers/net/hamradio/baycom_ser_fdx.c
@@ -416,10 +416,10 @@ static int ser12_open(struct net_device *dev)
if (!dev || !bc)
return -ENXIO;
if (!dev->base_addr || dev->base_addr > 0xffff-SER12_EXTENT ||
- dev->irq < 2 || dev->irq > NR_IRQS) {
+ dev->irq < 2 || dev->irq > nr_irqs) {
printk(KERN_INFO "baycom_ser_fdx: invalid portnumber (max %u) "
"or irq (2 <= irq <= %d)\n",
- 0xffff-SER12_EXTENT, NR_IRQS);
+ 0xffff-SER12_EXTENT, nr_irqs);
return -ENXIO;
}
if (bc->baud < 300 || bc->baud > 4800) {
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index 45ae9d1..c17e39b 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -1465,7 +1465,7 @@ static void ...Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
drivers/pci/intr_remapping.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index bb642cc..980566e 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -22,7 +22,7 @@ static DEFINE_SPINLOCK(irq_2_ir_lock);
int irq_remapped(int irq)
{
- if (irq > NR_IRQS)
+ if (irq > nr_irqs)
return 0;
if (!irq_2_iommu[irq].iommu)
@@ -35,7 +35,7 @@ int get_irte(int irq, struct irte *entry)
{
int index;
- if (!entry || irq > NR_IRQS)
+ if (!entry || irq > nr_irqs)
return -1;
spin_lock(&irq_2_ir_lock);
@@ -126,7 +126,7 @@ int map_irq_to_irte_handle(int irq, u16 *sub_handle)
int index;
spin_lock(&irq_2_ir_lock);
- if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+ if (irq >= nr_irqs || !irq_2_iommu[irq].iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
@@ -140,7 +140,7 @@ int map_irq_to_irte_handle(int irq, u16 *sub_handle)
int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
{
spin_lock(&irq_2_ir_lock);
- if (irq >= NR_IRQS || irq_2_iommu[irq].iommu) {
+ if (irq >= nr_irqs || irq_2_iommu[irq].iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
@@ -158,7 +158,7 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
{
spin_lock(&irq_2_ir_lock);
- if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+ if (irq >= nr_irqs || !irq_2_iommu[irq].iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
@@ -180,7 +180,7 @@ int modify_irte(int irq, struct irte *irte_modified)
struct intel_iommu *iommu;
spin_lock(&irq_2_ir_lock);
- if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+ if (irq >= nr_irqs || !irq_2_iommu[irq].iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
@@ -205,7 +205,7 @@ int flush_irte(int irq)
...Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- drivers/pcmcia/at91_cf.c | 2 +- drivers/pcmcia/vrc4171_card.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 6849685..194c8ba 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c @@ -273,7 +273,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) goto fail0d; cf->socket.pci_irq = board->irq_pin; } else - cf->socket.pci_irq = NR_IRQS + 1; + cf->socket.pci_irq = nr_irqs + 1; /* pcmcia layer only remaps "real" memory not iospace */ cf->socket.io_offset = (unsigned long) diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index eee2f1c..b2c4124 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -639,7 +639,7 @@ static int __devinit vrc4171_card_setup(char *options) int irq; options += 4; irq = simple_strtoul(options, &options, 0); - if (irq >= 0 && irq < NR_IRQS) + if (irq >= 0 && irq < nr_irqs) vrc4171_irq = irq; if (*options != ',') -- 1.5.4.5 --
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
drivers/rtc/rtc-vr41xx.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index 884b635..834dcc6 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -360,7 +360,7 @@ static int __devinit rtc_probe(struct platform_device *pdev)
spin_unlock_irq(&rtc_lock);
aie_irq = platform_get_irq(pdev, 0);
- if (aie_irq < 0 || aie_irq >= NR_IRQS) {
+ if (aie_irq < 0 || aie_irq >= nr_irqs) {
retval = -EBUSY;
goto err_device_unregister;
}
@@ -371,7 +371,7 @@ static int __devinit rtc_probe(struct platform_device *pdev)
goto err_device_unregister;
pie_irq = platform_get_irq(pdev, 1);
- if (pie_irq < 0 || pie_irq >= NR_IRQS)
+ if (pie_irq < 0 || pie_irq >= nr_irqs)
goto err_free_irq;
retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED,
--
1.5.4.5
--
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- drivers/scsi/aha152x.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index b5a868d..1e5478a 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -337,7 +337,7 @@ CMD_INC_RESID(struct scsi_cmnd *cmd, int inc) #else #define IRQ_MIN 9 #if defined(__PPC) -#define IRQ_MAX (NR_IRQS-1) +#define IRQ_MAX (nr_irqs-1) #else #define IRQ_MAX 12 #endif -- 1.5.4.5 --
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
drivers/serial/8250.c | 2 +-
drivers/serial/amba-pl010.c | 2 +-
drivers/serial/amba-pl011.c | 2 +-
drivers/serial/cpm_uart/cpm_uart_core.c | 2 +-
drivers/serial/m32r_sio.c | 4 ++--
drivers/serial/serial_core.c | 2 +-
drivers/serial/serial_lh7a40x.c | 2 +-
drivers/serial/sh-sci.c | 2 +-
drivers/serial/ucc_uart.c | 2 +-
9 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 71c8e68..f8f1015 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2479,7 +2479,7 @@ static void serial8250_config_port(struct uart_port *port, int flags)
static int
serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
{
- if (ser->irq >= NR_IRQS || ser->irq < 0 ||
+ if (ser->irq >= nr_irqs || ser->irq < 0 ||
ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
ser->type == PORT_STARTECH)
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 90b56c2..7156268 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -512,7 +512,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
int ret = 0;
if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
ret = -EINVAL;
- if (ser->irq < 0 || ser->irq >= NR_IRQS)
+ if (ser->irq < 0 || ser->irq >= nr_irqs)
ret = -EINVAL;
if (ser->baud_base < 9600)
ret = -EINVAL;
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 9d08f27..b718004 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -572,7 +572,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
int ret = 0;
if (ser->type != PORT_UNKNOWN && ser->type != ...Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
fs/proc/proc_misc.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index ded9698..1968251 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -503,7 +503,7 @@ static int show_stat(struct seq_file *p, void *v)
struct timespec boottime;
unsigned int *per_irq_sum;
- per_irq_sum = kzalloc(sizeof(unsigned int)*NR_IRQS, GFP_KERNEL);
+ per_irq_sum = kzalloc(sizeof(unsigned int)*nr_irqs, GFP_KERNEL);
if (!per_irq_sum)
return -ENOMEM;
@@ -525,7 +525,7 @@ static int show_stat(struct seq_file *p, void *v)
softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
- for (j = 0; j < NR_IRQS; j++) {
+ for (j = 0; j < nr_irqs; j++) {
unsigned int temp = kstat_cpu(i).irqs[j];
sum += temp;
per_irq_sum[j] += temp;
@@ -571,7 +571,7 @@ static int show_stat(struct seq_file *p, void *v)
}
seq_printf(p, "intr %llu", (unsigned long long)sum);
- for (i = 0; i < NR_IRQS; i++)
+ for (i = 0; i < nr_irqs; i++)
seq_printf(p, " %u", per_irq_sum[i]);
seq_printf(p,
@@ -625,13 +625,13 @@ static const struct file_operations proc_stat_operations = {
*/
static void *int_seq_start(struct seq_file *f, loff_t *pos)
{
- return (*pos <= NR_IRQS) ? pos : NULL;
+ return (*pos <= nr_irqs) ? pos : NULL;
}
static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
{
(*pos)++;
- if (*pos > NR_IRQS)
+ if (*pos > nr_irqs)
return NULL;
return pos;
}
--
1.5.4.5
--
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- drivers/xen/events.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/xen/events.c b/drivers/xen/events.c index a083703..8e329c2 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -139,7 +139,7 @@ static void init_evtchn_cpu_bindings(void) #ifdef CONFIG_SMP int i; /* By default all event channels notify CPU#0. */ - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) irq_desc[i].affinity = cpumask_of_cpu(0); #endif @@ -223,12 +223,12 @@ static int find_unbound_irq(void) int irq; /* Only allocate from dynirq range */ - for (irq = 0; irq < NR_IRQS; irq++) + for (irq = 0; irq < nr_irqs; irq++) if (irq_bindcount[irq] == 0) break; - if (irq == NR_IRQS) - panic("No available IRQ to bind to: increase NR_IRQS!\n"); + if (irq == nr_irqs) + panic("No available IRQ to bind to: increase nr_irqs!\n"); return irq; } @@ -761,7 +761,7 @@ void xen_irq_resume(void) mask_evtchn(evtchn); /* No IRQ <-> event-channel mappings. */ - for (irq = 0; irq < NR_IRQS; irq++) + for (irq = 0; irq < nr_irqs; irq++) irq_info[irq].evtchn = 0; /* zap event-channel binding */ for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) @@ -793,7 +793,7 @@ void __init xen_init_IRQ(void) mask_evtchn(i); /* Dynamic IRQ space is currently unbound. Zero the refcnts. */ - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) irq_bindcount[i] = 0; irq_ctx_init(smp_processor_id()); -- 1.5.4.5 --
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
drivers/char/random.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index fdbdcfc..872669e 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -558,7 +558,13 @@ struct timer_rand_state {
};
static struct timer_rand_state input_timer_state;
+
+#ifdef CONFIG_HAVE_DYN_ARRAY
+static struct timer_rand_state **irq_timer_state;
+DEFINE_DYN_ARRAY(irq_timer_state, sizeof(struct timer_rand_state *), nr_irqs, PAGE_SIZE, NULL);
+#else
static struct timer_rand_state *irq_timer_state[NR_IRQS];
+#endif
/*
* This function adds entropy to the entropy "pool" by using timing
--
1.5.4.5
--
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
drivers/pci/intr_remapping.c | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index 980566e..a7302d5 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -11,12 +11,19 @@ static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
static int ir_ioapic_num;
int intr_remapping_enabled;
-static struct {
+struct irq_2_iommu {
struct intel_iommu *iommu;
u16 irte_index;
u16 sub_handle;
u8 irte_mask;
-} irq_2_iommu[NR_IRQS];
+};
+
+#ifdef CONFIG_HAVE_DYNA_ARRAY
+static struct irq_2_iommu *irq_2_iommu;
+DEFINE_DYN_ARRAY(irq_2_iommu, sizeof(struct irq_2_iommu), nr_irqs, PAGE_SIZE, NULL);
+#else
+static struct irq_2_iommu irq_2_iommu[NR_IRQS];
+#endif
static DEFINE_SPINLOCK(irq_2_ir_lock);
--
1.5.4.5
--
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
include/linux/irq.h | 4 ++++
kernel/irq/handle.c | 31 +++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index bd69d90..c22e870 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -181,7 +181,11 @@ struct irq_desc {
const char *name;
} ____cacheline_internodealigned_in_smp;
+#ifdef CONFIG_HAVE_DYN_ARRAY
+extern struct irq_desc *irq_desc;
+#else
extern struct irq_desc irq_desc[NR_IRQS];
+#endif
/*
* Migration helpers for obsolete names, they will go away:
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index e9d022c..e94eeca 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -48,6 +48,36 @@ handle_bad_irq(unsigned int irq, struct irq_desc *desc)
* Controller mappings for all interrupt sources:
*/
int nr_irqs = NR_IRQS;
+
+#ifdef CONFIG_HAVE_DYN_ARRAY
+static struct irq_desc irq_desc_init __initdata = {
+ .status = IRQ_DISABLED,
+ .chip = &no_irq_chip,
+ .handle_irq = handle_bad_irq,
+ .depth = 1,
+ .lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
+#ifdef CONFIG_SMP
+ .affinity = CPU_MASK_ALL
+#endif
+};
+
+static void __init init_work(void *data)
+{
+ struct dyn_array *da = data;
+ int i;
+ struct irq_desc *desc;
+
+ desc = *da->name;
+
+ for (i = 0; i < *da->nr; i++)
+ memcpy(&desc[i], &irq_desc_init, sizeof(struct irq_desc));
+}
+
+struct irq_desc *irq_desc;
+DEFINE_DYN_ARRAY(irq_desc, sizeof(struct irq_desc), nr_irqs, PAGE_SIZE, init_work);
+
+#else
+
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
@@ -60,6 +90,7 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
#endif
}
};
+#endif
/*
* What should we do if we get a hw irq event on an illegal vector?
--
1.5.4.5
--
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
include/linux/kernel_stat.h | 4 ++++
kernel/sched.c | 5 ++++-
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index cf9f40a..fe1f7fe 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -28,7 +28,11 @@ struct cpu_usage_stat {
struct kernel_stat {
struct cpu_usage_stat cpustat;
+#ifdef CONFIG_HAVE_DYN_ARRAY
+ unsigned int *irqs;
+#else
unsigned int irqs[NR_IRQS];
+#endif
};
DECLARE_PER_CPU(struct kernel_stat, kstat);
diff --git a/kernel/sched.c b/kernel/sched.c
index 55cb4ce..21c0839 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4021,9 +4021,12 @@ static inline void idle_balance(int cpu, struct rq *rq)
#endif
DEFINE_PER_CPU(struct kernel_stat, kstat);
-
EXPORT_PER_CPU_SYMBOL(kstat);
+#ifdef CONFIG_HAVE_DYN_ARRAY
+DEFINE_PER_CPU_DYN_ARRAY_ADDR(per_cpu__kstat_irqs, per_cpu__kstat.irqs, sizeof(unsigned int), nr_irqs, sizeof(unsigned long), NULL);
+#endif
+
/*
* Return p->sum_exec_runtime plus any more ns on the sched_clock
* that have not yet been banked in case the task is currently running.
--
1.5.4.5
--
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/io_apic_32.c | 54 +++++++++++++++++++++++++++++++++--------
arch/x86/kernel/io_apic_64.c | 28 ++++++++++++++++-----
arch/x86/kernel/setup.c | 6 ++++
3 files changed, 70 insertions(+), 18 deletions(-)
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index d5953ff..a0ce64c 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -70,7 +70,7 @@ int timer_through_8259 __initdata;
*/
int sis_apic_bug = -1;
-int first_free_entry = NR_IRQS;
+int first_free_entry;
/*
* # of IRQ routing registers
*/
@@ -98,10 +98,7 @@ static int disable_timer_pin_1 __initdata;
* Rough estimation of how many shared IRQs there are, can
* be changed anytime.
*/
-#define MAX_PLUS_SHARED_IRQS NR_IRQS
-#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
-
-int pin_map_size = PIN_MAP_SIZE;
+int pin_map_size;
/*
* This is performance-critical, we want to do it O(1)
@@ -112,7 +109,9 @@ int pin_map_size = PIN_MAP_SIZE;
static struct irq_pin_list {
int apic, pin, next;
-} irq_2_pin[PIN_MAP_SIZE];
+} *irq_2_pin;
+
+DEFINE_DYN_ARRAY(irq_2_pin, sizeof(struct irq_pin_list), pin_map_size, 16, NULL);
struct io_apic {
unsigned int index;
@@ -403,9 +402,28 @@ static struct irq_cpu_info {
#define CPU_TO_PACKAGEINDEX(i) (first_cpu(per_cpu(cpu_sibling_map, i)))
-static cpumask_t balance_irq_affinity[NR_IRQS] = {
- [0 ... NR_IRQS-1] = CPU_MASK_ALL
-};
+static cpumask_t balance_irq_affinity_init __initdata = CPU_MASK_ALL;
+
+static cpumask_t *balance_irq_affinity;
+
+
+static void __init irq_affinity_init_work(void *data)
+{
+ struct dyn_array *da = data;
+
+ int i;
+ struct balance_irq_affinity *affinity;
+
+ affinity = *da->name;
+
+ for (i = 0; i < *da->nr; i++)
+ memcpy(&affinity[i], &balance_irq_affinity_init,
+ sizeof(struct balance_irq_affinity));
+
+}
+
+DEFINE_DYN_ARRAY(balance_irq_affinity, sizeof(struct ...Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/acpi/boot.c | 30 ++++++++++++++++++++++++++++--
include/asm-x86/mpspec.h | 1 +
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 27ef365..443cb30 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -962,6 +962,29 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
nr_ioapics++;
}
+int get_nr_irqs_via_madt(void)
+{
+ int idx;
+ int nr = 0;
+
+ for (idx = 0; idx < nr_ioapics; idx++) {
+ if (mp_ioapic_routing[idx].gsi_end > nr)
+ nr = mp_ioapic_routing[idx].gsi_end;
+ }
+
+ nr++;
+
+ /* double it for hotplug and msi and nmi */
+ nr <<= 1;
+
+ /* something wrong ? */
+ if (nr < 32)
+ nr = 32;
+
+ return nr;
+
+}
+
static void assign_to_mp_irq(struct mp_config_intsrc *m,
struct mp_config_intsrc *mp_irq)
{
@@ -1259,9 +1282,12 @@ static int __init acpi_parse_madt_ioapic_entries(void)
return count;
}
+
+ nr_irqs = get_nr_irqs_via_madt();
+
count =
acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr,
- NR_IRQ_VECTORS);
+ nr_irqs);
if (count < 0) {
printk(KERN_ERR PREFIX
"Error parsing interrupt source overrides entry\n");
@@ -1281,7 +1307,7 @@ static int __init acpi_parse_madt_ioapic_entries(void)
count =
acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src,
- NR_IRQ_VECTORS);
+ nr_irqs);
if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
/* TBD: Cleanup to allow fallback to MPS */
diff --git a/include/asm-x86/mpspec.h b/include/asm-x86/mpspec.h
index 118da36..5daa0f4 100644
--- a/include/asm-x86/mpspec.h
+++ b/include/asm-x86/mpspec.h
@@ -59,6 +59,7 @@ extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
u32 gsi);
extern void mp_config_acpi_legacy_irqs(void);
extern int ...Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- include/asm-x86/irq_vectors.h | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/include/asm-x86/irq_vectors.h b/include/asm-x86/irq_vectors.h index 0817a19..821ff99 100644 --- a/include/asm-x86/irq_vectors.h +++ b/include/asm-x86/irq_vectors.h @@ -127,8 +127,6 @@ #endif /* VISWS */ -#define NR_IRQ_VECTORS NR_IRQS - /* Voyager specific defines */ /* These define the CPIs we use in linux */ #define VIC_CPI_LEVEL0 0 -- 1.5.4.5 --
add CONFIG_HAVE_SPARSE_IRQ to for use condensed array preallocate 32 irq_desc, and irq_desc() will try to get more. v2: accrording to Eric, change get_irq_desc() to irq_desc() Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/Kconfig | 4 + arch/alpha/kernel/irq.c | 19 ++- arch/alpha/kernel/irq_alpha.c | 5 +- arch/alpha/kernel/irq_i8259.c | 8 +- arch/alpha/kernel/irq_pyxis.c | 9 +- arch/alpha/kernel/irq_srm.c | 9 +- arch/alpha/kernel/sys_alcor.c | 9 +- arch/alpha/kernel/sys_cabriolet.c | 8 +- arch/alpha/kernel/sys_dp264.c | 9 +- arch/alpha/kernel/sys_eb64p.c | 8 +- arch/alpha/kernel/sys_eiger.c | 7 +- arch/alpha/kernel/sys_jensen.c | 21 ++-- arch/alpha/kernel/sys_marvel.c | 20 ++- arch/alpha/kernel/sys_mikasa.c | 8 +- arch/alpha/kernel/sys_noritake.c | 8 +- arch/alpha/kernel/sys_rawhide.c | 8 +- arch/alpha/kernel/sys_rx164.c | 8 +- arch/alpha/kernel/sys_sable.c | 8 +- arch/alpha/kernel/sys_takara.c | 8 +- arch/alpha/kernel/sys_titan.c | 8 +- arch/alpha/kernel/sys_wildfire.c | 19 ++-- arch/arm/common/gic.c | 2 +- arch/arm/kernel/irq.c | 12 +- arch/arm/mach-at91/gpio.c | 4 +- arch/arm/mach-davinci/gpio.c | 13 ++- arch/arm/mach-ep93xx/core.c | 4 +- arch/arm/mach-orion5x/irq.c | 8 +- arch/arm/mach-sa1100/h3600.c | 10 +- arch/arm/plat-mxc/gpio.c | 7 +- arch/arm/plat-omap/gpio.c | 10 ...
preallocate size is 32, and if is not enough, irq_cfg will more with alloc_bootmem or kzalloc
v2: fix typo about size of init_one_irq_cfg ... should use sizeof(struct irq_cfg)
v3: according to Eric, change get_irq_cfg() to irq_cfg()
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/io_apic_64.c | 182 ++++++++++++++++++++++++++++++++---------
1 files changed, 142 insertions(+), 40 deletions(-)
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 9dbd189..1f70684 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -57,7 +57,11 @@
#define __apicdebuginit(type) static type __init
+struct irq_cfg;
+
struct irq_cfg {
+ unsigned int irq;
+ struct irq_cfg *next;
cpumask_t domain;
cpumask_t old_domain;
unsigned move_cleanup_count;
@@ -67,34 +71,112 @@ struct irq_cfg {
/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
static struct irq_cfg irq_cfg_legacy[] __initdata = {
- [0] = { .domain = CPU_MASK_ALL, .vector = IRQ0_VECTOR, },
- [1] = { .domain = CPU_MASK_ALL, .vector = IRQ1_VECTOR, },
- [2] = { .domain = CPU_MASK_ALL, .vector = IRQ2_VECTOR, },
- [3] = { .domain = CPU_MASK_ALL, .vector = IRQ3_VECTOR, },
- [4] = { .domain = CPU_MASK_ALL, .vector = IRQ4_VECTOR, },
- [5] = { .domain = CPU_MASK_ALL, .vector = IRQ5_VECTOR, },
- [6] = { .domain = CPU_MASK_ALL, .vector = IRQ6_VECTOR, },
- [7] = { .domain = CPU_MASK_ALL, .vector = IRQ7_VECTOR, },
- [8] = { .domain = CPU_MASK_ALL, .vector = IRQ8_VECTOR, },
- [9] = { .domain = CPU_MASK_ALL, .vector = IRQ9_VECTOR, },
- [10] = { .domain = CPU_MASK_ALL, .vector = IRQ10_VECTOR, },
- [11] = { .domain = CPU_MASK_ALL, .vector = IRQ11_VECTOR, },
- [12] = { .domain = CPU_MASK_ALL, .vector = IRQ12_VECTOR, },
- [13] = { .domain = CPU_MASK_ALL, .vector = IRQ13_VECTOR, },
- [14] = { .domain = CPU_MASK_ALL, .vector = IRQ14_VECTOR, },
- [15] = { .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, },
+ [0] = { .irq = ...preallocate 32 irq_2_pin, and use get_one_free_irq_2_pin to get one
and link to irq_cfg if needed.
so don't waste one for no irq is enabled.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/io_apic_64.c | 162 +++++++++++++++++++++++++++++++-----------
1 files changed, 121 insertions(+), 41 deletions(-)
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 1f70684..c1941b7 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -58,10 +58,11 @@
#define __apicdebuginit(type) static type __init
struct irq_cfg;
-
+struct irq_pin_list;
struct irq_cfg {
unsigned int irq;
struct irq_cfg *next;
+ struct irq_pin_list *irq_2_pin;
cpumask_t domain;
cpumask_t old_domain;
unsigned move_cleanup_count;
@@ -232,13 +233,66 @@ int pin_map_size;
* between pins and IRQs.
*/
-static struct irq_pin_list {
- short apic, pin;
- int next;
-} *irq_2_pin;
+struct irq_pin_list {
+ int apic, pin;
+ struct irq_pin_list *next;
+};
+
+static struct irq_pin_list *irq_2_pin_head;
+/* fill one page ? */
+static int nr_irq_2_pin = 0x100;
+static struct irq_pin_list *irq_2_pin_ptr;
+static void __init irq_2_pin_init_work(void *data)
+{
+ struct dyn_array *da = data;
+ struct irq_pin_list *pin;
+ int i;
+
+ pin = *da->name;
+
+ for (i = 1; i < *da->nr; i++)
+ pin[i-1].next = &pin[i];
+
+ irq_2_pin_ptr = &pin[0];
+}
+DEFINE_DYN_ARRAY(irq_2_pin_head, sizeof(struct irq_pin_list), nr_irq_2_pin, PAGE_SIZE, irq_2_pin_init_work);
+
+static struct irq_pin_list *get_one_free_irq_2_pin(void)
+{
+ struct irq_pin_list *pin;
+ int i;
+
+ pin = irq_2_pin_ptr;
+
+ if (pin) {
+ irq_2_pin_ptr = pin->next;
+ pin->next = NULL;
+ return pin;
+ }
+
+ /*
+ * we run out of pre-allocate ones, allocate more
+ */
+ printk(KERN_DEBUG "try to get more irq_2_pin %d\n", nr_irq_2_pin);
+
+ if (after_bootmem)
+ pin = kzalloc(sizeof(struct irq_pin_list)*nr_irq_2_pin,
+ ...so could remove timer_rand_state pointer array
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
drivers/char/random.c | 31 ++++++++++++++++++++-----------
include/linux/irq.h | 2 ++
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 872669e..d683576 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -559,13 +559,6 @@ struct timer_rand_state {
static struct timer_rand_state input_timer_state;
-#ifdef CONFIG_HAVE_DYN_ARRAY
-static struct timer_rand_state **irq_timer_state;
-DEFINE_DYN_ARRAY(irq_timer_state, sizeof(struct timer_rand_state *), nr_irqs, PAGE_SIZE, NULL);
-#else
-static struct timer_rand_state *irq_timer_state[NR_IRQS];
-#endif
-
/*
* This function adds entropy to the entropy "pool" by using timing
* delays. It uses the timer_rand_state structure to make an estimate
@@ -653,11 +646,20 @@ EXPORT_SYMBOL_GPL(add_input_randomness);
void add_interrupt_randomness(int irq)
{
- if (irq >= nr_irqs || irq_timer_state[irq] == NULL)
+ struct timer_rand_state *state;
+ struct irq_desc *desc;
+
+ if (irq >= nr_irqs)
+ return;
+
+ desc = irq_desc(irq);
+ state = desc->timer_rand_state;
+
+ if (state == NULL)
return;
DEBUG_ENT("irq event %d\n", irq);
- add_timer_randomness(irq_timer_state[irq], 0x100 + irq);
+ add_timer_randomness(state, 0x100 + irq);
}
#ifdef CONFIG_BLOCK
@@ -916,8 +918,15 @@ module_init(rand_initialize);
void rand_initialize_irq(int irq)
{
struct timer_rand_state *state;
+ struct irq_desc *desc;
+
+ if (irq >= nr_irqs)
+ return;
+
+ desc = irq_desc(irq);
+ state = desc->timer_rand_state;
- if (irq >= nr_irqs || irq_timer_state[irq])
+ if (state)
return;
/*
@@ -926,7 +935,7 @@ void rand_initialize_irq(int irq)
*/
state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
if (state)
- irq_timer_state[irq] = state;
+ desc->timer_rand_state = state;
}
#ifdef ...based Eric's patch ... together mold it with dyn_array for irq_desc, will allcate kstat_irqs for nr_irq_desc alltogether if needed. -- at that point nr_cpus is known already. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/alpha/kernel/irq.c | 2 +- arch/alpha/kernel/irq_alpha.c | 2 +- arch/arm/kernel/irq.c | 2 +- arch/arm/mach-ns9xxx/irq.c | 3 +- arch/avr32/kernel/irq.c | 2 +- arch/cris/kernel/irq.c | 2 +- arch/frv/kernel/irq.c | 2 +- arch/h8300/kernel/irq.c | 2 +- arch/ia64/kernel/irq.c | 2 +- arch/ia64/kernel/irq_ia64.c | 8 +- arch/m32r/kernel/irq.c | 2 +- arch/m68k/kernel/ints.c | 6 +- arch/m68k/sun3/sun3ints.c | 8 +- arch/mips/kernel/irq.c | 2 +- arch/mips/sgi-ip22/ip22-int.c | 2 +- arch/mips/sgi-ip22/ip22-time.c | 2 +- arch/mips/sibyte/bcm1480/smp.c | 2 +- arch/mips/sibyte/sb1250/irq.c | 2 +- arch/mips/sibyte/sb1250/smp.c | 2 +- arch/mn10300/kernel/irq.c | 2 +- arch/parisc/kernel/irq.c | 2 +- arch/powerpc/kernel/irq.c | 2 +- arch/powerpc/platforms/cell/interrupt.c | 2 +- arch/s390/kernel/irq.c | 2 +- arch/s390/kernel/s390_ext.c | 2 +- arch/sh/kernel/irq.c | 2 +- arch/sparc/kernel/irq.c | 7 +- arch/sparc/kernel/sun4d_irq.c | 5 +- arch/sparc64/kernel/irq.c | 2 +- arch/sparc64/kernel/time.c | 2 +- arch/um/kernel/irq.c | 2 +- arch/x86/kernel/io_apic_32.c | 2 +- arch/x86/kernel/irq_32.c | 4 +- arch/x86/kernel/irq_64.c | 4 +- arch/x86/kernel/visws_quirks.c ...
so don't all irq_desc at begining to allocate all.
and only call that when needed
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/io_apic_64.c | 6 +++---
arch/x86/kernel/irq_64.c | 5 ++---
arch/x86/kernel/irqinit_64.c | 17 +++++------------
fs/proc/proc_misc.c | 7 +++++--
include/linux/irq.h | 18 ++++++++++++++++++
kernel/irq/handle.c | 27 ++++++++++++++++++++++++---
kernel/irq/internals.h | 4 ++--
kernel/irq/manage.c | 2 +-
kernel/irq/proc.c | 10 +++++-----
9 files changed, 65 insertions(+), 31 deletions(-)
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index c1941b7..784a882 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -1845,10 +1845,10 @@ unmask:
static void ir_irq_migration(struct work_struct *work)
{
- int irq;
+ unsigned int irq;
+ struct irq_desc *desc;
- for (irq = 0; irq < nr_irqs; irq++) {
- struct irq_desc *desc = irq_desc(irq);
+ for_each_irq_desc(irq, desc) {
if (desc->status & IRQ_MOVE_PENDING) {
unsigned long flags;
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 61fe896..f79b68b 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -224,17 +224,16 @@ void fixup_irqs(cpumask_t map)
{
unsigned int irq;
static int warned;
+ struct irq_desc *desc;
- for (irq = 0; irq < nr_irqs; irq++) {
+ for_each_irq_desc(irq, desc) {
cpumask_t mask;
int break_affinity = 0;
int set_affinity = 1;
- struct irq_desc *desc;
if (irq == 2)
continue;
- desc = irq_desc(irq);
/* interrupt's are disabled at this point */
spin_lock(&desc->lock);
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c
index 583db8b..4c55edf 100644
--- a/arch/x86/kernel/irqinit_64.c
+++ b/arch/x86/kernel/irqinit_64.c
@@ -142,25 +142,18 @@ static void __init init_ISA_irqs (void)
init_bsp_APIC();
...so don't all irq_cfg at begining to allocate all.
and only call that when needed
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/io_apic_64.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 784a882..1d1a70d 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -129,6 +129,9 @@ static void __init init_work(void *data)
cfg[i-1].next = &cfg[i];
}
+#define for_each_irq_cfg(cfg) \
+ for(cfg = irq_cfgx; cfg && cfg->irq != -1U; cfg = cfg->next)
+
static struct irq_cfg *irq_cfgx;
DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irq_cfg, PAGE_SIZE, init_work);
@@ -1063,20 +1066,18 @@ static void __setup_vector_irq(int cpu)
/* Initialize vector_irq on a new cpu */
/* This function must be called with vector_lock held */
int irq, vector;
+ struct irq_cfg *cfg;
/* Mark the inuse vectors */
- for (irq = 0; irq < nr_irqs; ++irq) {
- struct irq_cfg *cfg = irq_cfg(irq);
-
+ for_each_irq_cfg(cfg) {
if (!cpu_isset(cpu, cfg->domain))
continue;
vector = cfg->vector;
+ irq = cfg->irq;
per_cpu(vector_irq, cpu)[vector] = irq;
}
/* Mark the free vectors */
for (vector = 0; vector < NR_VECTORS; ++vector) {
- struct irq_cfg *cfg;
-
irq = per_cpu(vector_irq, cpu)[vector];
if (irq < 0)
continue;
@@ -1312,6 +1313,7 @@ __apicdebuginit(void) print_IO_APIC(void)
union IO_APIC_reg_01 reg_01;
union IO_APIC_reg_02 reg_02;
unsigned long flags;
+ struct irq_cfg *cfg;
if (apic_verbosity == APIC_QUIET)
return;
@@ -1380,12 +1382,11 @@ __apicdebuginit(void) print_IO_APIC(void)
}
}
printk(KERN_DEBUG "IRQ to pin mappings:\n");
- for (i = 0; i < nr_irqs; i++) {
- struct irq_cfg *cfg = irq_cfg(i);
+ for_each_irq_cfg(cfg) {
struct irq_pin_list *entry = cfg->irq_2_pin;
if (!entry)
continue;
- printk(KERN_DEBUG "IRQ%d ", ...v2: fix checking about result irq_cfg_without_new, so could use msi again
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/io_apic_64.c | 29 ++++++++++++++++++++---------
arch/x86/kernel/irq_64.c | 2 +-
drivers/char/random.c | 4 ++++
fs/proc/proc_misc.c | 29 +++++++++++++++++------------
kernel/irq/chip.c | 28 +++++++++++++++++++++++++++-
kernel/irq/manage.c | 37 +++++++++++++++++++++++++++++++------
6 files changed, 100 insertions(+), 29 deletions(-)
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 1d1a70d..36d6387 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -135,6 +135,26 @@ static void __init init_work(void *data)
static struct irq_cfg *irq_cfgx;
DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irq_cfg, PAGE_SIZE, init_work);
+static struct irq_cfg *irq_cfg_without_new(unsigned int irq)
+{
+ struct irq_cfg *cfg;
+
+ BUG_ON(irq == -1U);
+
+ cfg = &irq_cfgx[0];
+ while (cfg) {
+ if (cfg->irq == irq)
+ return cfg;
+
+ if (cfg->irq == -1U) {
+ return NULL;
+ }
+ cfg = cfg->next;
+ }
+
+ return NULL;
+}
+
static struct irq_cfg *irq_cfg(unsigned int irq)
{
struct irq_cfg *cfg, *cfg_pri;
@@ -380,7 +400,6 @@ static inline void io_apic_sync(unsigned int apic)
struct irq_cfg *cfg; \
struct irq_pin_list *entry; \
\
- BUG_ON(irq >= nr_irqs); \
cfg = irq_cfg(irq); \
entry = cfg->irq_2_pin; \
for (;;) { \
@@ -460,7 +479,6 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, u8 vector)
struct irq_cfg *cfg;
struct irq_pin_list *entry;
- BUG_ON(irq >= nr_irqs);
cfg = irq_cfg(irq);
entry = cfg->irq_2_pin;
for (;;) {
@@ -529,7 +547,6 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin)
struct irq_cfg *cfg;
struct irq_pin_list *entry;
- BUG_ON(irq >= nr_irqs);
cfg = irq_cfg(irq);
entry = ...So could remove some duplicated calling to irq_desc
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/io_apic_32.c | 6 ++-
arch/x86/kernel/io_apic_64.c | 49 +++++++++++++------------------
arch/x86/kernel/irq_32.c | 3 +-
arch/x86/kernel/irq_64.c | 8 +++--
drivers/mfd/tc6393xb.c | 7 +++-
drivers/parisc/dino.c | 3 +-
drivers/parisc/eisa.c | 4 ++-
drivers/parisc/gsc.c | 3 +-
drivers/parisc/superio.c | 4 ++-
include/linux/irq.h | 30 +++++++++++++------
init/main.c | 5 +++
kernel/irq/chip.c | 26 +++++++++++++++-
kernel/irq/handle.c | 65 +++++++++++++++++++++++++++++++++++++++--
kernel/irq/manage.c | 8 +++++
kernel/irq/migration.c | 15 +++++----
15 files changed, 172 insertions(+), 64 deletions(-)
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index cb18dbb..7cb3411 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -1975,7 +1975,8 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
static void ack_ioapic_irq(unsigned int irq)
{
- move_native_irq(irq);
+ struct irq_desc *desc = irq_desc(irq);
+ move_native_irq(irq, desc);
ack_APIC_irq();
}
@@ -1983,8 +1984,9 @@ static void ack_ioapic_quirk_irq(unsigned int irq)
{
unsigned long v;
int i;
+ struct irq_desc *desc = irq_desc(irq);
- move_native_irq(irq);
+ move_native_irq(irq, desc);
/*
* It appears there is an erratum which affects at least version 0x11
* of I/O APIC (that's the 82093AA and cores integrated into various
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 36d6387..fc1c6ba 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -505,13 +505,12 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, u8 vector)
}
}
-static void set_ioapic_affinity_irq(unsigned int irq, ...so don't get new one that we don't need
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/irq_64.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 007e4a2..42b2c12 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -83,7 +83,10 @@ int show_interrupts(struct seq_file *p, void *v)
if (i < nr_irqs) {
unsigned any_count = 0;
- struct irq_desc *desc = irq_desc(i);
+ struct irq_desc *desc = irq_desc_without_new(i);
+
+ if (!desc)
+ return 0;
spin_lock_irqsave(&desc->lock, flags);
#ifndef CONFIG_SMP
--
1.5.4.5
--
So could only call that one time, when we call add_irq_2_pin
Singed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/io_apic_64.c | 16 +++++++++++-----
1 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index fc1c6ba..1466e4b 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -135,7 +135,7 @@ static void __init init_work(void *data)
static struct irq_cfg *irq_cfgx;
DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irq_cfg, PAGE_SIZE, init_work);
-static struct irq_cfg *irq_cfg_without_new(unsigned int irq)
+static struct irq_cfg *irq_cfg(unsigned int irq)
{
struct irq_cfg *cfg;
@@ -155,7 +155,7 @@ static struct irq_cfg *irq_cfg_without_new(unsigned int irq)
return NULL;
}
-static struct irq_cfg *irq_cfg(unsigned int irq)
+static struct irq_cfg *irq_cfg_with_new(unsigned int irq)
{
struct irq_cfg *cfg, *cfg_pri;
int i;
@@ -545,7 +545,8 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin)
struct irq_cfg *cfg;
struct irq_pin_list *entry;
- cfg = irq_cfg(irq);
+ /* first time to refer irq_cfg, so with new */
+ cfg = irq_cfg_with_new(irq);
entry = cfg->irq_2_pin;
if (!entry) {
entry = get_one_free_irq_2_pin();
@@ -1208,13 +1209,15 @@ static int setup_ioapic_entry(int apic, int irq,
static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq,
int trigger, int polarity)
{
- struct irq_cfg *cfg = irq_cfg(irq);
+ struct irq_cfg *cfg;
struct IO_APIC_route_entry entry;
cpumask_t mask;
if (!IO_APIC_IRQ(irq))
return;
+ cfg = irq_cfg(irq);
+
mask = TARGET_CPUS;
if (assign_irq_vector(irq, mask))
return;
@@ -2490,8 +2493,11 @@ int create_irq(void)
if (platform_legacy_irq(new))
continue;
cfg_new = irq_cfg(new);
- if (cfg_new->vector != 0)
+ if (cfg_new && cfg_new->vector != 0)
continue;
+ /* check if need to create one */
+ if ...So could only call that one time
Singed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/io_apic_64.c | 18 ++++++++++++------
arch/x86/kernel/irq_64.c | 4 ++--
arch/x86/kernel/irqinit_64.c | 3 ++-
fs/proc/proc_misc.c | 2 +-
include/linux/irq.h | 2 +-
kernel/irq/chip.c | 5 +++++
kernel/irq/handle.c | 23 +++++------------------
7 files changed, 28 insertions(+), 29 deletions(-)
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 1466e4b..f8baf58 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -1117,7 +1117,12 @@ static void ioapic_register_intr(int irq, unsigned long trigger)
{
struct irq_desc *desc;
- desc = irq_desc(irq);
+ /* first time to use this irq_desc */
+ if (irq < 16)
+ desc = irq_desc(irq);
+ else
+ desc = irq_desc_with_new(irq);
+
if (trigger)
desc->status |= IRQ_LEVEL;
else
@@ -3086,8 +3091,6 @@ void __init setup_ioapic_dest(void)
continue;
irq = pin_2_irq(irq_entry, ioapic, pin);
- desc = irq_desc(irq);
-
/* setup_IO_APIC_irqs could fail to get vector for some device
* when you have too many devices, because at that time only boot
* cpu is online.
@@ -3098,13 +3101,16 @@ void __init setup_ioapic_dest(void)
irq_trigger(irq_entry),
irq_polarity(irq_entry));
#ifdef CONFIG_INTR_REMAP
- else if (intr_remapping_enabled)
+ else if (intr_remapping_enabled) {
+ desc = irq_desc(irq);
set_ir_ioapic_affinity_irq(irq, desc, TARGET_CPUS);
+ }
#endif
- else
+ else {
+ desc = irq_desc(irq);
set_ioapic_affinity_irq(irq, desc, TARGET_CPUS);
+ }
}
-
}
}
#endif
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 42b2c12..7db6843 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -83,7 +83,7 @@ int show_interrupts(struct seq_file *p, void *v)
if (i < nr_irqs) {
unsigned ...so later don't need compare with -1U
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
include/linux/irq.h | 2 +-
kernel/irq/handle.c | 113 ++++++++++++++++++++++++++------------------------
2 files changed, 60 insertions(+), 55 deletions(-)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 0d9578e..d130119 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -223,7 +223,7 @@ extern struct irq_desc *irq_descX;
extern struct irq_desc *irq_descX;
#define for_each_irq_desc(irqX, desc) \
- for (desc = irq_descX, irqX = desc->irq; desc && irqX != -1U; desc = desc->next, irqX = desc ? desc->irq: -1U)
+ for (desc = irq_descX, irqX = desc->irq; desc; desc = desc->next, irqX = desc ? desc->irq: -1U)
#endif
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 194d815..0f5ea0c 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -111,6 +111,11 @@ static void init_kstat_irqs(struct irq_desc *desc, int nr_desc, int nr)
}
}
+#ifdef CONFIG_HAVE_SPARSE_IRQ
+static struct irq_desc *irq_descX_free;
+struct irq_desc *irq_descX;
+#endif
+
static void __init init_work(void *data)
{
struct dyn_array *da = data;
@@ -126,13 +131,16 @@ static void __init init_work(void *data)
#endif
}
+ /* init kstat_irqs, nr_cpu_ids is ready already */
+ init_kstat_irqs(desc, *da->nr, nr_cpu_ids);
+
#ifdef CONFIG_HAVE_SPARSE_IRQ
for (i = 1; i < *da->nr; i++)
desc[i-1].next = &desc[i];
-#endif
- /* init kstat_irqs, nr_cpu_ids is ready already */
- init_kstat_irqs(desc, *da->nr, nr_cpu_ids);
+ irq_descX_free = irq_descX;
+ irq_descX = NULL;
+#endif
}
#ifdef CONFIG_HAVE_SPARSE_IRQ
@@ -147,23 +155,17 @@ static int __init parse_nr_irq_desc(char *arg)
early_param("nr_irq_desc", parse_nr_irq_desc);
-struct irq_desc *irq_descX;
DEFINE_DYN_ARRAY(irq_descX, sizeof(struct irq_desc), nr_irq_desc, PAGE_SIZE, init_work);
struct irq_desc *irq_desc(unsigned int irq)
{
struct irq_desc *desc;
...so later don't need compare with -1U
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/io_apic_64.c | 90 ++++++++++++++++++++++++++---------------
1 files changed, 57 insertions(+), 33 deletions(-)
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index f8baf58..305ccb5 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -111,44 +111,44 @@ static void init_one_irq_cfg(struct irq_cfg *cfg)
memcpy(cfg, &irq_cfg_init, sizeof(struct irq_cfg));
}
+static struct irq_cfg *irq_cfgx;
+static struct irq_cfg *irq_cfgx_free;
static void __init init_work(void *data)
{
struct dyn_array *da = data;
struct irq_cfg *cfg;
+ int legacy_count;
int i;
cfg = *da->name;
memcpy(cfg, irq_cfg_legacy, sizeof(irq_cfg_legacy));
- i = sizeof(irq_cfg_legacy)/sizeof(irq_cfg_legacy[0]);
- for (; i < *da->nr; i++)
+ legacy_count = sizeof(irq_cfg_legacy)/sizeof(irq_cfg_legacy[0]);
+ for (i = legacy_count; i < *da->nr; i++)
init_one_irq_cfg(&cfg[i]);
for (i = 1; i < *da->nr; i++)
cfg[i-1].next = &cfg[i];
+
+ irq_cfgx_free = &irq_cfgx[legacy_count];
+ irq_cfgx[legacy_count - 1].next = NULL;
}
#define for_each_irq_cfg(cfg) \
- for(cfg = irq_cfgx; cfg && cfg->irq != -1U; cfg = cfg->next)
+ for(cfg = irq_cfgx; cfg; cfg = cfg->next)
-static struct irq_cfg *irq_cfgx;
DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irq_cfg, PAGE_SIZE, init_work);
static struct irq_cfg *irq_cfg(unsigned int irq)
{
struct irq_cfg *cfg;
- BUG_ON(irq == -1U);
-
- cfg = &irq_cfgx[0];
+ cfg = irq_cfgx;
while (cfg) {
if (cfg->irq == irq)
return cfg;
- if (cfg->irq == -1U) {
- return NULL;
- }
cfg = cfg->next;
}
@@ -161,44 +161,68 @@ static struct irq_cfg *irq_cfg_with_new(unsigned int irq)
int i;
int count = 0;
- BUG_ON(irq == -1U);
-
- cfg_pri = cfg = &irq_cfgx[0];
+ cfg_pri = cfg = irq_cfgx;
while (cfg) {
if (cfg->irq == irq)
...loop with irq_desc list
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
arch/x86/kernel/irq_64.c | 31 ++++++++++++++++++++++++-------
fs/proc/proc_misc.c | 28 ++++++++++++++++++++++++----
2 files changed, 48 insertions(+), 11 deletions(-)
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 7db6843..ef96ce7 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -70,9 +70,27 @@ static inline void stack_overflow_check(struct pt_regs *regs)
int show_interrupts(struct seq_file *p, void *v)
{
- int i = *(loff_t *) v, j;
+ int i, j;
struct irqaction * action;
unsigned long flags;
+ unsigned int entries;
+ struct irq_desc *desc;
+ int tail = 0;
+
+#ifdef CONFIG_HAVE_SPARSE_IRQ
+ desc = (struct irq_desc *)v;
+ entries = -1U;
+ i = desc->irq;
+ if (!desc->next)
+ tail = 1;
+#else
+ entries = nr_irqs - 1;
+ i = *(loff_t *) v;
+ if (i == nr_irqs)
+ tail = 1;
+ else
+ desc = irq_desc(i);
+#endif
if (i == 0) {
seq_printf(p, " ");
@@ -81,12 +99,8 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
}
- if (i < nr_irqs) {
+ if (i <= entries) {
unsigned any_count = 0;
- struct irq_desc *desc = irq_desc(i);
-
- if (!desc)
- return 0;
spin_lock_irqsave(&desc->lock, flags);
#ifndef CONFIG_SMP
@@ -116,7 +130,9 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
skip:
spin_unlock_irqrestore(&desc->lock, flags);
- } else if (i == nr_irqs) {
+ }
+
+ if (tail) {
seq_printf(p, "NMI: ");
for_each_online_cpu(j)
seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count);
@@ -155,6 +171,7 @@ skip:
seq_printf(p, " Spurious interrupts\n");
seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
}
+
return 0;
}
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index c9ee1f7..15901c7 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -633,15 +633,36 @@ static const struct file_operations ...loop with irq_desc list
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
fs/proc/proc_misc.c | 18 ++++++++----------
1 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 15901c7..c001d1a 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -567,20 +567,18 @@ static int show_stat(struct seq_file *p, void *v)
}
seq_printf(p, "intr %llu", (unsigned long long)sum);
- /* sum again ? it could be updated? have another field in irq_desc?*/
- for (j = 0; j < nr_irqs; j++) {
+ /* sum again ? it could be updated? */
+ for_each_irq_desc(j, desc) {
per_irq_sum = 0;
- desc = irq_desc(j);
- if (desc)
- for_each_possible_cpu(i) {
- unsigned int temp;
+ for_each_possible_cpu(i) {
+ unsigned int temp;
- temp = kstat_irqs_cpu(j, i);
- per_irq_sum += temp;
- }
+ temp = kstat_irqs_cpu(j, i);
+ per_irq_sum += temp;
+ }
- seq_printf(p, " %u", per_irq_sum);
+ seq_printf(p, " %u:%u", j, per_irq_sum);
}
seq_printf(p,
--
1.5.4.5
--
preallocate some irq_2_iommu, and use get_one_free_irq_2_iomm to get one
and link to irq_desc if needed.
---
drivers/pci/intr_remapping.c | 213 ++++++++++++++++++++++++++++++++----------
include/linux/irq.h | 4 +
2 files changed, 169 insertions(+), 48 deletions(-)
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index a7302d5..78896b3 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -18,41 +18,136 @@ struct irq_2_iommu {
u8 irte_mask;
};
-#ifdef CONFIG_HAVE_DYNA_ARRAY
-static struct irq_2_iommu *irq_2_iommu;
-DEFINE_DYN_ARRAY(irq_2_iommu, sizeof(struct irq_2_iommu), nr_irqs, PAGE_SIZE, NULL);
+#ifdef CONFIG_HAVE_SPARSE_IRQ
+static struct irq_2_iommu *irq_2_iommuX;
+/* fill one page ? */
+static int nr_irq_2_iommu = 0x100;
+static int irq_2_iommu_index;
+DEFINE_DYN_ARRAY(irq_2_iommuX, sizeof(struct irq_2_iommu), nr_irq_2_iommu, PAGE_SIZE, NULL);
+
+extern void *__alloc_bootmem_nopanic(unsigned long size,
+ unsigned long align,
+ unsigned long goal);
+
+static struct irq_2_iommu *get_one_free_irq_2_iommu(int not_used)
+{
+ struct irq_2_iommu *iommu;
+ unsigned long total_bytes;
+
+ if (irq_2_iommu_index >= nr_irq_2_iommu) {
+ /*
+ * we run out of pre-allocate ones, allocate more
+ */
+ printk(KERN_DEBUG "try to get more irq_2_iommu %d\n", nr_irq_2_iommu);
+
+ total_bytes = sizeof(struct irq_2_iommu)*nr_irq_2_iommu;
+
+ if (after_bootmem)
+ iommu = kzalloc(total_bytes, GFP_ATOMIC);
+ else
+ iommu = __alloc_bootmem_nopanic(total_bytes, PAGE_SIZE, 0);
+
+ if (!iommu)
+ panic("can not get more irq_2_iommu\n");
+
+ irq_2_iommuX = iommu;
+ irq_2_iommu_index = 0;
+ }
+
+ iommu = &irq_2_iommuX[irq_2_iommu_index];
+ irq_2_iommu_index++;
+ return iommu;
+}
+
+static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
+{
+ struct irq_desc *desc;
+
+ desc = irq_desc(irq);
+
+ BUG_ON(!desc);
+
+ return ...This patch is ok, but this approach is fundamentally broken. Only 19 architectures use GENERIC_HARDIRQS The only required interface is interrupt.h not irq.h So you may not replace NR_IRQS with nr_irqs in anything other then genirq code and some architecture code. Doing so will break the build on several architectures. Eric --
some platforms will not use include/linux/irq.h and kernel/irq/handle.c ? YH --
Also, what's the point, if it's just a renaming? -hpa --
that is the start point. nr_irqs is variable, and will be probed later. and use that number to init dyn_alloc. YH --
YH. In my conception the code in kernel/irq.c that today does: struct irq_desc *desc; if (irq >= NR_IRQS) return -EINVAL; desc = irq_desc + irq; Should become: struct irq_desc *desc; desc = irq_desc(irq); if (!desc) return -EINVAL; Eric --
OK.
also want to introduce dummy
struct irq_desc
{
unsigned int irq;
};
in linux/interrupt.h if GENERIC_HARDIRQS is not defined.
so could have same interface
irq_desc()
and
for_each_irq_desc(irq, desc)
YH
--
What would use it? irq_desc doesn't even exist if GENERIC_HARDIRQS are not defined. Far far in the future we may want to introduce an opaque type struct irq. For use with linux/interrupt.h Allowing things like irq_request(struct irq *irq, ...); For now those kinds of interfaces should be internal to the genirq code. Eric --
From: Yinghai Lu <yhlu.kernel@gmail.com>
Date: Fri, 8 Aug 2008 13:56:15 -0700
Subject: [PATCH 31/42] replace loop with nr_irqs for proc/stat
so don't all irq_desc at begining to allocate all.
and only call that when needed
v2: make sure arch without GENERIC_HARDIRQS works too
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
fs/proc/proc_misc.c | 50 ++++++++++++++++++++++++++++++++++++--------------
1 file changed, 36 insertions(+), 14 deletions(-)
Index: linux-2.6/fs/proc/proc_misc.c
===================================================================
--- linux-2.6.orig/fs/proc/proc_misc.c
+++ linux-2.6/fs/proc/proc_misc.c
@@ -495,17 +495,16 @@ static const struct file_operations proc
static int show_stat(struct seq_file *p, void *v)
{
- int i;
+ int i, j;
unsigned long jif;
cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
cputime64_t guest;
u64 sum = 0;
struct timespec boottime;
- unsigned int *per_irq_sum;
-
- per_irq_sum = kzalloc(sizeof(unsigned int)*nr_irqs, GFP_KERNEL);
- if (!per_irq_sum)
- return -ENOMEM;
+ unsigned int per_irq_sum;
+#ifdef CONFIG_GENERIC_HARDIRQS
+ struct irq_desc *desc;
+#endif
user = nice = system = idle = iowait =
irq = softirq = steal = cputime64_zero;
@@ -514,8 +513,6 @@ static int show_stat(struct seq_file *p,
jif = boottime.tv_sec;
for_each_possible_cpu(i) {
- int j;
-
user = cputime64_add(user, kstat_cpu(i).cpustat.user);
nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
system = cputime64_add(system, kstat_cpu(i).cpustat.system);
@@ -525,10 +522,12 @@ static int show_stat(struct seq_file *p,
softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
guest = cputime64_add(guest, ...Yes. interrupt.h is the common infrastructure. Eric --
On Fri, Aug 8, 2008 at 11:07 PM, Eric W. Biederman ok, will move to that file. YH --
???? If you introduce a new concept like valid_irq that is fine. interrupt.h is the interface to drivers! Let me say this clearly. DO NOT CHANGE THE INTERFACE TO DEVICE DRIVERS! Eric --
please check
Index: linux-2.6/include/linux/interrupt.h
===================================================================
--- linux-2.6.orig/include/linux/interrupt.h
+++ linux-2.6/include/linux/interrupt.h
@@ -15,6 +15,8 @@
#include <asm/ptrace.h>
#include <asm/system.h>
+extern int nr_irqs;
+
/*
* These correspond to the IORESOURCE_IRQ_* defines in
* linux/ioport.h to select the interrupt line behaviour. When
Index: linux-2.6/arch/m68k/kernel/ints.c
===================================================================
--- linux-2.6.orig/arch/m68k/kernel/ints.c
+++ linux-2.6/arch/m68k/kernel/ints.c
@@ -46,6 +46,8 @@
#include <asm/q40ints.h>
#endif
+int nr_irqs = NR_IRQS;
+
extern u32 auto_irqhandler_fixup[];
extern u32 user_irqhandler_fixup[];
extern u16 user_irqvec_fixup[];
Index: linux-2.6/arch/s390/kernel/irq.c
===================================================================
--- linux-2.6.orig/arch/s390/kernel/irq.c
+++ linux-2.6/arch/s390/kernel/irq.c
@@ -17,6 +17,8 @@
#include <linux/proc_fs.h>
#include <linux/profile.h>
+int nr_irqs = NR_IRQS;
+
/*
* show_interrupts is needed by /proc/interrupts.
*/
Index: linux-2.6/arch/sparc/kernel/irq.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/irq.c
+++ linux-2.6/arch/sparc/kernel/irq.c
@@ -55,6 +55,9 @@
#define SMP_NOP2
#define SMP_NOP3
#endif /* SMP */
+
+int nr_irqs = NR_IRQS;
+
unsigned long __raw_local_irq_save(void)
{
unsigned long retval;
Index: linux-2.6/kernel/irq/handle.c
===================================================================
--- linux-2.6.orig/kernel/irq/handle.c
+++ linux-2.6/kernel/irq/handle.c
@@ -47,6 +47,7 @@ handle_bad_irq(unsigned int irq, struct
*
* Controller mappings for all interrupt sources:
*/
+int nr_irqs = NR_IRQS;
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
--
So I'm still clearly missing something about this... if we need sparse IRQs in the first place (which we do), what's the point of the dyn_array? -hpa --
x86_64: support CONFIG_HAVE_SPARSE_IRQ and CONFIG_DYN_ARRAY x86_32: support CONFIG_DYN_ARRAY some arches could use dyn_array with probing nr_irqs and it could be 32 and much less than 224. some could have that like 512. and those arch may not need to mess up with sparse_irq at first point. but still could get some flexibilty about that array size. YH --
As an x86 maintainer, I definitely do not want x86-64 and x86-32 to diverge unless there is an extremely strong reason to. Other architectures may speak for themselves, but why not just support sparse IRQs on x86-32 *and* -64 and skip the dyn_array variant? -=hpa --
after we merged io_apic_32.c into io_apic_64.c. also I want to kill irq balance in io_apic_32.c, but no one say anything about it. also dyn_array could have other user in addition to nr_irqs. i will dig it out like NR_CPUS/nr_cpu_ids related array. and Mike tried to put every thing to PER_CPU instead of array, maybe some case array would be effient than that. that make dyn_array some usage. YH --
Let the potental other users worry about it at that time. I understand it's a neat feature, but that doesn't justify adding it at this time if it's not the right thing forthe job. I really don't want to see x86-32 and x86-64 diverge more, and I really don't want to throw in additional complexity if we don't really need it. -hpa --
Hm... I tried to check this in as a separate topic branch, but it conflicts against both linus and against tip:x86/core, which are the branches we usually base topic branches on. I really am not convinced about the whole dyn_array concept, and *especially* not having divergences between 32 and 64 bits with regards to sparse IRQs. Furthermore, there are a number of checkpatch errors for this patch series, most of which appear legit. So again... any reason to not just have sparse IRQs and be done with it? -hpa --
Ingo said, I only need to work on tip/master, and you guys will sort it out. Eric's NR_IRQS patch for 2.6.27 is not in tip yet. --- Andrew picked up already another reason: dyn_arry == static in some case, so I could make sure compiling work well between static/dyn_array with sparse_irq. YH --
Yes. Let's see if we can get that regression fix in there for 2.6.27... Eric --
please check the attached v6 v6: fixed checkpatch errors.., only left warning about lines > 80 chars. put Eric's patch about NR_IRQS at first could be applied cleanly to tip/master Thanks Yinghai Lu
