* [PATCH] x86: 64bit support more than 256 irq v2
@ 2008-07-29 21:14 Yinghai Lu
2008-07-29 22:16 ` Yinghai Lu
` (2 more replies)
0 siblings, 3 replies; 44+ messages in thread
From: Yinghai Lu @ 2008-07-29 21:14 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman,
Dhaval Giani
Cc: linux-kernel
Dhaval Giani got:
kernel BUG at arch/x86/kernel/io_apic_64.c:357!
invalid opcode: 0000 [1] SMP
CPU 24
Modules linked in:
Pid: 1, comm: swapper Not tainted 2.6.27-rc1-autokern1 #1
RIP: 0010:[<ffffffff8021bb2e>] [<ffffffff8021bb2e>] add_pin_to_irq+0x8e/0xa0
RSP: 0018:ffff88032e4b9b30 EFLAGS: 00010216
RAX: 00000000000000f0 RBX: 00000000000000f0 RCX: 0000000000000000
RDX: 000000000000afaf RSI: 0000000000000046 RDI: ffffffff80738234
RBP: 0000000000000006 R08: 0000000000000000 R09: ffff8800280992c0
R10: 0000000000000000 R11: ffffffff80372060 R12: 0000000000000018
R13: 0000000000000001 R14: 0000000000000018 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff880bfe733540(0000) knlGS:0000000000000000
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 0000000000000000 CR3: 0000000000201000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process swapper (pid: 1, threadinfo ffff88032e4b8000, task ffff880bfe4ca050)
Stack: 00000000000000f0 0000000000000006 0000000000000001 ffffffff8021bbbe
00000000000000f0 0000000000000001 0000000000000000 ffff88032e4b9c0c
00000000000000f0 ffffffff80218d81 00000000000000f0 0000000000000000
Call Trace:
[<ffffffff8021bbbe>] ? io_apic_set_pci_routing+0x7e/0xa0
[<ffffffff80218d81>] ? mp_register_gsi+0xb1/0xd0
[<ffffffff80218e0c>] ? acpi_register_gsi+0x6c/0x70
[<ffffffff80392f30>] ? acpi_pci_irq_enable+0x178/0x260
[<ffffffff80392cdd>] ? acpi_pci_allocate_irq+0x0/0x4c
[<ffffffff80370657>] ? pci_enable_resources+0x27/0x160
[<ffffffff8036be6a>] ? do_pci_enable_device+0x4a/0x70
[<ffffffff8036bee1>] ? __pci_enable_device_flags+0x51/0x60
[<ffffffff804e01e8>] ? tg3_init_one+0x58/0x1640
[<ffffffff8022a980>] ? default_wake_function+0x0/0x10
[<ffffffff8022efd8>] ? set_cpus_allowed_ptr+0xe8/0x110
[<ffffffff8036e28f>] ? pci_device_probe+0xdf/0x130
[<ffffffff803c2416>] ? driver_probe_device+0x96/0x1a0
[<ffffffff803c25a9>] ? __driver_attach+0x89/0x90
[<ffffffff803c2520>] ? __driver_attach+0x0/0x90
[<ffffffff803c1a8d>] ? bus_for_each_dev+0x4d/0x80
[<ffffffff8028e168>] ? kmem_cache_alloc+0xc8/0xf0
[<ffffffff803c1f7e>] ? bus_add_driver+0xae/0x220
[<ffffffff803c2836>] ? driver_register+0x56/0x130
[<ffffffff8036e548>] ? __pci_register_driver+0x68/0xb0
[<ffffffff806cf8e0>] ? tg3_init+0x0/0x20
[<ffffffff806b15b1>] ? do_one_initcall+0x41/0x180
[<ffffffff802d8a08>] ? create_proc_entry+0x58/0xa0
[<ffffffff80261cc4>] ? register_irq_proc+0xd4/0xf0
[<ffffffff806b1b53>] ? kernel_init+0x133/0x190
[<ffffffff8020c529>] ? child_rip+0xa/0x11
[<ffffffff806b1a20>] ? kernel_init+0x0/0x190
[<ffffffff8020c51f>] ? child_rip+0x0/0x11
Code: 89 05 2b 54 42 00 7f 27 48 0f bf c1 48 8d 14 00 48 c1 e0 03 48 29 d0 48 8d 90 c0 5e 73 80 66 89 2a 66 44 89 62 02 5b 5d 41 5c c3 <0f> 0b eb fe 48 c7 c7 c8 db 5c 80 31 c0 e8 60 7e 01 00 48 83 ec
RIP [<ffffffff8021bb2e>] add_pin_to_irq+0x8e/0xa0
RSP <ffff88032e4b9b30>
his system (x3950) has 8 ioapic, irq > 256
caused by
commit 9b7dc567d03d74a1fbae84e88949b6a60d922d82
Author: Thomas Gleixner <tglx@linutronix.de>
Date: Fri May 2 20:10:09 2008 +0200
x86: unify interrupt vector defines
The interrupt vector defines are copied 4 times around with minimal
differences. Move them all into asm-x86/irq_vectors.h
64bit allow same vector for different cpu to serve different irq
also change next in irq_pin_list from short to int. because for 4096 NR_IRQS
is 2^(8+12).
v2: accoding to Eric W. Biederman, change to NR_IRQ_VECTORS to NR_IRQS
use NR_VECTORS*NR_CPUS directly
need to create that array dynamically later
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Tested-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
---
arch/x86/kernel/io_apic_64.c | 3 ++-
include/asm-x86/irq_vectors.h | 14 ++++++--------
2 files changed, 8 insertions(+), 9 deletions(-)
Index: linux-2.6/include/asm-x86/irq_vectors.h
===================================================================
--- linux-2.6.orig/include/asm-x86/irq_vectors.h
+++ linux-2.6/include/asm-x86/irq_vectors.h
@@ -113,28 +113,26 @@
# if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_PARAVIRT) || defined(CONFIG_X86_VISWS)
+#ifdef CONFIG_X86_64
+# define NR_IRQS (NR_VECTORS * NR_CPUS)
+#else
# define NR_IRQS 224
-
-# if (224 >= 32 * NR_CPUS)
-# define NR_IRQ_VECTORS NR_IRQS
-# else
-# define NR_IRQ_VECTORS (32 * NR_CPUS)
-# endif
+#endif
# else /* IO_APIC || PARAVIRT */
# define NR_IRQS 16
-# define NR_IRQ_VECTORS NR_IRQS
# endif
#else /* !VISWS && !VOYAGER */
# define NR_IRQS 224
-# define NR_IRQ_VECTORS NR_IRQS
#endif /* VISWS */
+#define NR_IRQ_VECTORS NR_IRQS
+
/* Voyager specific defines */
/* These define the CPIs we use in linux */
#define VIC_CPI_LEVEL0 0
Index: linux-2.6/arch/x86/kernel/io_apic_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/io_apic_64.c
+++ linux-2.6/arch/x86/kernel/io_apic_64.c
@@ -140,7 +140,8 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BU
*/
static struct irq_pin_list {
- short apic, pin, next;
+ short apic, pin;
+ int next;
} irq_2_pin[PIN_MAP_SIZE];
struct io_apic {
^ permalink raw reply [flat|nested] 44+ messages in thread* Re: [PATCH] x86: 64bit support more than 256 irq v2 2008-07-29 21:14 [PATCH] x86: 64bit support more than 256 irq v2 Yinghai Lu @ 2008-07-29 22:16 ` Yinghai Lu 2008-07-29 23:22 ` Eric W. Biederman 2008-07-30 4:38 ` RFC [PATCH] x86: introduce nr_irqs for 64bit Yinghai Lu 2 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-29 22:16 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani Cc: linux-kernel On Tue, Jul 29, 2008 at 2:14 PM, Yinghai Lu <yhlu.kernel@gmail.com> wrote: > > Dhaval Giani got: > kernel BUG at arch/x86/kernel/io_apic_64.c:357! > invalid opcode: 0000 [1] SMP > CPU 24 > Modules linked in: > Pid: 1, comm: swapper Not tainted 2.6.27-rc1-autokern1 #1 > RIP: 0010:[<ffffffff8021bb2e>] [<ffffffff8021bb2e>] add_pin_to_irq+0x8e/0xa0 > RSP: 0018:ffff88032e4b9b30 EFLAGS: 00010216 > RAX: 00000000000000f0 RBX: 00000000000000f0 RCX: 0000000000000000 > RDX: 000000000000afaf RSI: 0000000000000046 RDI: ffffffff80738234 > RBP: 0000000000000006 R08: 0000000000000000 R09: ffff8800280992c0 > R10: 0000000000000000 R11: ffffffff80372060 R12: 0000000000000018 > R13: 0000000000000001 R14: 0000000000000018 R15: 0000000000000000 > FS: 0000000000000000(0000) GS:ffff880bfe733540(0000) knlGS:0000000000000000 > CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b > CR2: 0000000000000000 CR3: 0000000000201000 CR4: 00000000000006e0 > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 > DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 > Process swapper (pid: 1, threadinfo ffff88032e4b8000, task ffff880bfe4ca050) > Stack: 00000000000000f0 0000000000000006 0000000000000001 ffffffff8021bbbe > 00000000000000f0 0000000000000001 0000000000000000 ffff88032e4b9c0c > 00000000000000f0 ffffffff80218d81 00000000000000f0 0000000000000000 > Call Trace: > [<ffffffff8021bbbe>] ? io_apic_set_pci_routing+0x7e/0xa0 > [<ffffffff80218d81>] ? mp_register_gsi+0xb1/0xd0 > [<ffffffff80218e0c>] ? acpi_register_gsi+0x6c/0x70 > [<ffffffff80392f30>] ? acpi_pci_irq_enable+0x178/0x260 > [<ffffffff80392cdd>] ? acpi_pci_allocate_irq+0x0/0x4c > [<ffffffff80370657>] ? pci_enable_resources+0x27/0x160 > [<ffffffff8036be6a>] ? do_pci_enable_device+0x4a/0x70 > [<ffffffff8036bee1>] ? __pci_enable_device_flags+0x51/0x60 > [<ffffffff804e01e8>] ? tg3_init_one+0x58/0x1640 > [<ffffffff8022a980>] ? default_wake_function+0x0/0x10 > [<ffffffff8022efd8>] ? set_cpus_allowed_ptr+0xe8/0x110 > [<ffffffff8036e28f>] ? pci_device_probe+0xdf/0x130 > [<ffffffff803c2416>] ? driver_probe_device+0x96/0x1a0 > [<ffffffff803c25a9>] ? __driver_attach+0x89/0x90 > [<ffffffff803c2520>] ? __driver_attach+0x0/0x90 > [<ffffffff803c1a8d>] ? bus_for_each_dev+0x4d/0x80 > [<ffffffff8028e168>] ? kmem_cache_alloc+0xc8/0xf0 > [<ffffffff803c1f7e>] ? bus_add_driver+0xae/0x220 > [<ffffffff803c2836>] ? driver_register+0x56/0x130 > [<ffffffff8036e548>] ? __pci_register_driver+0x68/0xb0 > [<ffffffff806cf8e0>] ? tg3_init+0x0/0x20 > [<ffffffff806b15b1>] ? do_one_initcall+0x41/0x180 > [<ffffffff802d8a08>] ? create_proc_entry+0x58/0xa0 > [<ffffffff80261cc4>] ? register_irq_proc+0xd4/0xf0 > [<ffffffff806b1b53>] ? kernel_init+0x133/0x190 > [<ffffffff8020c529>] ? child_rip+0xa/0x11 > [<ffffffff806b1a20>] ? kernel_init+0x0/0x190 > [<ffffffff8020c51f>] ? child_rip+0x0/0x11 > > > Code: 89 05 2b 54 42 00 7f 27 48 0f bf c1 48 8d 14 00 48 c1 e0 03 48 29 d0 48 8d 90 c0 5e 73 80 66 89 2a 66 44 89 62 02 5b 5d 41 5c c3 <0f> 0b eb fe 48 c7 c7 c8 db 5c 80 31 c0 e8 60 7e 01 00 48 83 ec > RIP [<ffffffff8021bb2e>] add_pin_to_irq+0x8e/0xa0 > RSP <ffff88032e4b9b30> > > his system (x3950) has 8 ioapic, irq > 256 > > caused by > commit 9b7dc567d03d74a1fbae84e88949b6a60d922d82 > Author: Thomas Gleixner <tglx@linutronix.de> > Date: Fri May 2 20:10:09 2008 +0200 > > x86: unify interrupt vector defines > > The interrupt vector defines are copied 4 times around with minimal > differences. Move them all into asm-x86/irq_vectors.h > > > 64bit allow same vector for different cpu to serve different irq > > also change next in irq_pin_list from short to int. because for 4096 NR_IRQS > is 2^(8+12). > > v2: accoding to Eric W. Biederman, change to NR_IRQ_VECTORS to NR_IRQS > use NR_VECTORS*NR_CPUS directly > > need to create that array dynamically later seems MAX_SMP doesn't like it. even can not be built. working on make NR_IRQS related array to be allocated dynamically. YH ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] x86: 64bit support more than 256 irq v2 2008-07-29 21:14 [PATCH] x86: 64bit support more than 256 irq v2 Yinghai Lu 2008-07-29 22:16 ` Yinghai Lu @ 2008-07-29 23:22 ` Eric W. Biederman 2008-07-30 4:38 ` RFC [PATCH] x86: introduce nr_irqs for 64bit Yinghai Lu 2 siblings, 0 replies; 44+ messages in thread From: Eric W. Biederman @ 2008-07-29 23:22 UTC (permalink / raw) To: Yinghai Lu Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, linux-kernel Yinghai Lu <yhlu.kernel@gmail.com> writes: > Dhaval Giani got: > kernel BUG at arch/x86/kernel/io_apic_64.c:357! > invalid opcode: 0000 [1] SMP > CPU 24 > Modules linked in: > Pid: 1, comm: swapper Not tainted 2.6.27-rc1-autokern1 #1 > RIP: 0010:[<ffffffff8021bb2e>] [<ffffffff8021bb2e>] add_pin_to_irq+0x8e/0xa0 > RSP: 0018:ffff88032e4b9b30 EFLAGS: 00010216 > RAX: 00000000000000f0 RBX: 00000000000000f0 RCX: 0000000000000000 > RDX: 000000000000afaf RSI: 0000000000000046 RDI: ffffffff80738234 > RBP: 0000000000000006 R08: 0000000000000000 R09: ffff8800280992c0 > R10: 0000000000000000 R11: ffffffff80372060 R12: 0000000000000018 > R13: 0000000000000001 R14: 0000000000000018 R15: 0000000000000000 > FS: 0000000000000000(0000) GS:ffff880bfe733540(0000) knlGS:0000000000000000 > CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b > CR2: 0000000000000000 CR3: 0000000000201000 CR4: 00000000000006e0 > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 > DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 > Process swapper (pid: 1, threadinfo ffff88032e4b8000, task ffff880bfe4ca050) > Stack: 00000000000000f0 0000000000000006 0000000000000001 ffffffff8021bbbe > 00000000000000f0 0000000000000001 0000000000000000 ffff88032e4b9c0c > 00000000000000f0 ffffffff80218d81 00000000000000f0 0000000000000000 > Call Trace: > [<ffffffff8021bbbe>] ? io_apic_set_pci_routing+0x7e/0xa0 > [<ffffffff80218d81>] ? mp_register_gsi+0xb1/0xd0 > [<ffffffff80218e0c>] ? acpi_register_gsi+0x6c/0x70 > [<ffffffff80392f30>] ? acpi_pci_irq_enable+0x178/0x260 > [<ffffffff80392cdd>] ? acpi_pci_allocate_irq+0x0/0x4c > [<ffffffff80370657>] ? pci_enable_resources+0x27/0x160 > [<ffffffff8036be6a>] ? do_pci_enable_device+0x4a/0x70 > [<ffffffff8036bee1>] ? __pci_enable_device_flags+0x51/0x60 > [<ffffffff804e01e8>] ? tg3_init_one+0x58/0x1640 > [<ffffffff8022a980>] ? default_wake_function+0x0/0x10 > [<ffffffff8022efd8>] ? set_cpus_allowed_ptr+0xe8/0x110 > [<ffffffff8036e28f>] ? pci_device_probe+0xdf/0x130 > [<ffffffff803c2416>] ? driver_probe_device+0x96/0x1a0 > [<ffffffff803c25a9>] ? __driver_attach+0x89/0x90 > [<ffffffff803c2520>] ? __driver_attach+0x0/0x90 > [<ffffffff803c1a8d>] ? bus_for_each_dev+0x4d/0x80 > [<ffffffff8028e168>] ? kmem_cache_alloc+0xc8/0xf0 > [<ffffffff803c1f7e>] ? bus_add_driver+0xae/0x220 > [<ffffffff803c2836>] ? driver_register+0x56/0x130 > [<ffffffff8036e548>] ? __pci_register_driver+0x68/0xb0 > [<ffffffff806cf8e0>] ? tg3_init+0x0/0x20 > [<ffffffff806b15b1>] ? do_one_initcall+0x41/0x180 > [<ffffffff802d8a08>] ? create_proc_entry+0x58/0xa0 > [<ffffffff80261cc4>] ? register_irq_proc+0xd4/0xf0 > [<ffffffff806b1b53>] ? kernel_init+0x133/0x190 > [<ffffffff8020c529>] ? child_rip+0xa/0x11 > [<ffffffff806b1a20>] ? kernel_init+0x0/0x190 > [<ffffffff8020c51f>] ? child_rip+0x0/0x11 > > > Code: 89 05 2b 54 42 00 7f 27 48 0f bf c1 48 8d 14 00 48 c1 e0 03 48 29 d0 48 8d > 90 c0 5e 73 80 66 89 2a 66 44 89 62 02 5b 5d 41 5c c3 <0f> 0b eb fe 48 c7 c7 c8 > db 5c 80 31 c0 e8 60 7e 01 00 48 83 ec > RIP [<ffffffff8021bb2e>] add_pin_to_irq+0x8e/0xa0 > RSP <ffff88032e4b9b30> > > his system (x3950) has 8 ioapic, irq > 256 > > caused by > commit 9b7dc567d03d74a1fbae84e88949b6a60d922d82 > Author: Thomas Gleixner <tglx@linutronix.de> > Date: Fri May 2 20:10:09 2008 +0200 > > x86: unify interrupt vector defines > > The interrupt vector defines are copied 4 times around with minimal > differences. Move them all into asm-x86/irq_vectors.h > > > 64bit allow same vector for different cpu to serve different irq > > also change next in irq_pin_list from short to int. because for 4096 NR_IRQS > is 2^(8+12). > > v2: accoding to Eric W. Biederman, change to NR_IRQ_VECTORS to NR_IRQS > use NR_VECTORS*NR_CPUS directly Apologies I didn't mean to set NR_IRQS to NR_VECTORS*NR_CPUS literally. That simply is a waste of space in current systems. The original (NR_CPUS*32)+224 is much more reasonable and should cover all of the real world cases. With respect to NR_IRQ_VECTORS if we can get per_irq vectors on x86_32 we can kill it. I had forgotten a detail. irq_vector on x86_32 needs to be sized with NR_IRQS. However acpi_table_parse_madt needs to the true limit on the number of irq sources we can handle which is NR_IRQ_VECTORS. It works because we have cool irq merging and other weird nonsense on x86_32 to fit within 256 irqs. On x86_64 they are the same. Eric ^ permalink raw reply [flat|nested] 44+ messages in thread
* RFC [PATCH] x86: introduce nr_irqs for 64bit 2008-07-29 21:14 [PATCH] x86: 64bit support more than 256 irq v2 Yinghai Lu 2008-07-29 22:16 ` Yinghai Lu 2008-07-29 23:22 ` Eric W. Biederman @ 2008-07-30 4:38 ` Yinghai Lu 2008-07-30 10:09 ` Ingo Molnar 2008-07-30 10:11 ` [PATCH] x86: introduce nr_irqs for 64bit v2 Yinghai Lu 2 siblings, 2 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-30 4:38 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel add DEFINE_DYN_ARRAY for dynamical array support todo: 1. convert x86 32bit and other arch 2. nr_irqs auto probe via acpi_oem_check? Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/io_apic_32.c | 1 arch/x86/kernel/io_apic_64.c | 59 ++++++++++++++++++++++++-------------- arch/x86/kernel/irq_64.c | 8 ++--- arch/x86/kernel/irqinit_64.c | 2 - arch/x86/kernel/setup.c | 7 ++++ arch/x86/kernel/vmlinux_64.lds.S | 3 + drivers/char/hpet.c | 2 - drivers/char/random.c | 4 +- drivers/pci/intr_remapping.c | 22 +++++++------- drivers/serial/8250.c | 8 +++-- drivers/serial/serial_core.c | 2 - drivers/xen/events.c | 12 +++---- fs/proc/proc_misc.c | 10 +++--- include/asm-generic/vmlinux.lds.h | 7 ++++ include/asm-x86/irq.h | 4 ++ include/asm-x86/irq_vectors.h | 14 +++------ include/linux/init.h | 23 ++++++++++++++ include/linux/irq.h | 2 - init/main.c | 20 ++++++++++++ kernel/irq/autoprobe.c | 10 +++--- kernel/irq/chip.c | 20 ++++++------ kernel/irq/handle.c | 34 +++++++++++++++------ kernel/irq/manage.c | 16 +++++----- kernel/irq/proc.c | 2 - kernel/irq/resend.c | 4 +- kernel/irq/spurious.c | 4 +- 26 files changed, 199 insertions(+), 101 deletions(-) Index: linux-2.6/arch/x86/kernel/io_apic_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/io_apic_32.c +++ linux-2.6/arch/x86/kernel/io_apic_32.c @@ -70,6 +70,7 @@ int timer_through_8259 __initdata; */ int sis_apic_bug = -1; +int nr_irqs = NR_IRQS; /* * # of IRQ routing registers */ Index: linux-2.6/arch/x86/kernel/io_apic_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/io_apic_64.c +++ linux-2.6/arch/x86/kernel/io_apic_64.c @@ -66,7 +66,7 @@ struct irq_cfg { }; /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ -static struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = { +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, }, @@ -85,6 +85,19 @@ static struct irq_cfg irq_cfg[NR_IRQS] _ [15] = { .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, }, }; +static struct irq_cfg *irq_cfg; + +int nr_irqs; + +static void __init init_work(void *data) +{ + struct dyn_array *da = data; + + memcpy(*da->name, irq_cfg_legacy, sizeof(irq_cfg_legacy)); +} + +DEFINE_DYN_ARRAY(irq_cfg, sizeof(struct irq_cfg), nr_irqs, PAGE_SIZE, init_work); + static int assign_irq_vector(int irq, cpumask_t mask); int first_system_vector = 0xfe; @@ -129,8 +142,8 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BU * 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; /* * This is performance-critical, we want to do it O(1) @@ -140,8 +153,12 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BU */ static struct irq_pin_list { - short apic, pin, next; -} irq_2_pin[PIN_MAP_SIZE]; + short apic, pin; + int next; +} *irq_2_pin; + +DEFINE_DYN_ARRAY(irq_2_pin, sizeof(struct irq_pin_list), pin_map_size, sizeof(struct irq_pin_list), NULL); + struct io_apic { unsigned int index; @@ -224,7 +241,7 @@ static inline void io_apic_sync(unsigned int pin; \ struct irq_pin_list *entry = irq_2_pin + irq; \ \ - BUG_ON(irq >= NR_IRQS); \ + BUG_ON(irq >= nr_irqs); \ for (;;) { \ unsigned int reg; \ pin = entry->pin; \ @@ -301,7 +318,7 @@ static void __target_IO_APIC_irq(unsigne int apic, pin; struct irq_pin_list *entry = irq_2_pin + irq; - BUG_ON(irq >= NR_IRQS); + BUG_ON(irq >= nr_irqs); for (;;) { unsigned int reg; apic = entry->apic; @@ -358,19 +375,19 @@ static void set_ioapic_affinity_irq(unsi * shared ISA-space IRQs, so we have to support them. We are super * fast in the common case, and fast for shared ISA-space IRQs. */ +int first_free_entry; 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; - BUG_ON(irq >= NR_IRQS); + BUG_ON(irq >= nr_irqs); while (entry->next) entry = irq_2_pin + entry->next; 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: ran out of irq_2_pin entries!"); } entry->apic = apic; @@ -634,7 +651,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, best_guess = irq; } } - BUG_ON(best_guess >= NR_IRQS); + BUG_ON(best_guess >= nr_irqs); return best_guess; } @@ -766,7 +783,7 @@ static int pin_2_irq(int idx, int apic, irq += nr_ioapic_registers[i++]; irq += pin; } - BUG_ON(irq >= NR_IRQS); + BUG_ON(irq >= nr_irqs); return irq; } @@ -788,7 +805,7 @@ static int __assign_irq_vector(int irq, int cpu; struct irq_cfg *cfg; - BUG_ON((unsigned)irq >= NR_IRQS); + BUG_ON((unsigned)irq >= nr_irqs); cfg = &irq_cfg[irq]; /* Only try and allocate irqs on cpus that are present */ @@ -862,7 +879,7 @@ static void __clear_irq_vector(int irq) cpumask_t mask; int cpu, vector; - BUG_ON((unsigned)irq >= NR_IRQS); + BUG_ON((unsigned)irq >= nr_irqs); cfg = &irq_cfg[irq]; BUG_ON(!cfg->vector); @@ -882,7 +899,7 @@ static void __setup_vector_irq(int cpu) int irq, vector; /* Mark the inuse vectors */ - for (irq = 0; irq < NR_IRQS; ++irq) { + for (irq = 0; irq < nr_irqs; ++irq) { if (!cpu_isset(cpu, irq_cfg[irq].domain)) continue; vector = irq_cfg[irq].vector; @@ -1188,7 +1205,7 @@ __apicdebuginit(void) print_IO_APIC(void } } printk(KERN_DEBUG "IRQ to pin mappings:\n"); - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; @@ -1361,7 +1378,7 @@ void __init enable_IO_APIC(void) int i, apic; unsigned long flags; - for (i = 0; i < PIN_MAP_SIZE; i++) { + for (i = 0; i < pin_map_size; i++) { irq_2_pin[i].pin = -1; irq_2_pin[i].next = 0; } @@ -1655,7 +1672,7 @@ static void ir_irq_migration(struct work { int irq; - for (irq = 0; irq < NR_IRQS; irq++) { + for (irq = 0; irq < nr_irqs; irq++) { struct irq_desc *desc = irq_desc + irq; if (desc->status & IRQ_MOVE_PENDING) { unsigned long flags; @@ -1704,7 +1721,7 @@ asmlinkage void smp_irq_move_cleanup_int struct irq_desc *desc; struct irq_cfg *cfg; irq = __get_cpu_var(vector_irq)[vector]; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) continue; desc = irq_desc + irq; @@ -1862,7 +1879,7 @@ static inline void init_IO_APIC_traps(vo * Also, we've got to be careful not to trash gate * 0x80, because int 0x80 is hm, kind of importantish. ;) */ - for (irq = 0; irq < NR_IRQS ; irq++) { + for (irq = 0; irq < nr_irqs ; irq++) { if (IO_APIC_IRQ(irq) && !irq_cfg[irq].vector) { /* * Hmm.. We don't have an entry for this, @@ -2276,7 +2293,7 @@ int create_irq(void) irq = -ENOSPC; spin_lock_irqsave(&vector_lock, flags); - for (new = (NR_IRQS - 1); new >= 0; new--) { + for (new = (nr_irqs - 1); new >= 0; new--) { if (platform_legacy_irq(new)) continue; if (irq_cfg[new].vector != 0) Index: linux-2.6/arch/x86/kernel/irq_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/irq_64.c +++ linux-2.6/arch/x86/kernel/irq_64.c @@ -81,7 +81,7 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); } - if (i < NR_IRQS) { + if (i < nr_irqs) { unsigned any_count = 0; spin_lock_irqsave(&irq_desc[i].lock, flags); @@ -112,7 +112,7 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { + } else if (i == nr_irqs) { seq_printf(p, "NMI: "); for_each_online_cpu(j) seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count); @@ -201,7 +201,7 @@ asmlinkage unsigned int do_IRQ(struct pt stack_overflow_check(regs); #endif - if (likely(irq < NR_IRQS)) + if (likely(irq < nr_irqs)) generic_handle_irq(irq); else { if (!disable_apic) @@ -224,7 +224,7 @@ void fixup_irqs(cpumask_t map) unsigned int irq; static int warned; - for (irq = 0; irq < NR_IRQS; irq++) { + for (irq = 0; irq < nr_irqs; irq++) { cpumask_t mask; int break_affinity = 0; int set_affinity = 1; Index: linux-2.6/arch/x86/kernel/irqinit_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/irqinit_64.c +++ linux-2.6/arch/x86/kernel/irqinit_64.c @@ -142,7 +142,7 @@ static void __init init_ISA_irqs (void) init_bsp_APIC(); init_8259A(0); - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; Index: linux-2.6/arch/x86/kernel/setup.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup.c +++ linux-2.6/arch/x86/kernel/setup.c @@ -856,7 +856,14 @@ void __init setup_arch(char **cmdline_p) #endif prefill_possible_map(); + #ifdef CONFIG_X86_64 + /* need to wait for nr_cpu_ids settle down */ + nr_irqs = NR_VECTORS * nr_cpu_ids; + pin_map_size = nr_irqs * 2; + first_free_entry = nr_irqs; + printk(KERN_INFO "nr_irqs: %d\n", nr_irqs); + pre_alloc_dyn_array(); init_cpu_to_node(); #endif Index: linux-2.6/arch/x86/kernel/vmlinux_64.lds.S =================================================================== --- linux-2.6.orig/arch/x86/kernel/vmlinux_64.lds.S +++ linux-2.6/arch/x86/kernel/vmlinux_64.lds.S @@ -174,6 +174,9 @@ SECTIONS *(.x86cpuvendor.init) } __x86cpuvendor_end = .; + + DYN_ARRAY_INIT(8) + SECURITY_INIT . = ALIGN(8); Index: linux-2.6/drivers/char/hpet.c =================================================================== --- linux-2.6.orig/drivers/char/hpet.c +++ linux-2.6/drivers/char/hpet.c @@ -222,7 +222,7 @@ static void hpet_timer_set_irq(struct hp 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; } Index: linux-2.6/drivers/char/random.c =================================================================== --- linux-2.6.orig/drivers/char/random.c +++ linux-2.6/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; /* Index: linux-2.6/drivers/pci/intr_remapping.c =================================================================== --- linux-2.6.orig/drivers/pci/intr_remapping.c +++ linux-2.6/drivers/pci/intr_remapping.c @@ -11,18 +11,20 @@ static struct ioapic_scope ir_ioapic[MAX static int ir_ioapic_num; int intr_remapping_enabled; -static struct { +static struct irq_2_iommu { struct intel_iommu *iommu; u16 irte_index; u16 sub_handle; u8 irte_mask; -} irq_2_iommu[NR_IRQS]; +} *irq_2_iommu; + +DEFINE_DYN_ARRAY(irq_2_iommu, sizeof(struct irq_2_iommu), nr_irqs, PAGE_SIZE, NULL); 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 +37,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 +128,7 @@ int map_irq_to_irte_handle(int irq, u16 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 +142,7 @@ int map_irq_to_irte_handle(int irq, u16 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 +160,7 @@ int set_irte_irq(int irq, struct intel_i 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 +182,7 @@ int modify_irte(int irq, struct irte *ir 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 +207,7 @@ int flush_irte(int irq) 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; } @@ -248,7 +250,7 @@ int free_irte(int irq) 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; } Index: linux-2.6/drivers/serial/8250.c =================================================================== --- linux-2.6.orig/drivers/serial/8250.c +++ linux-2.6/drivers/serial/8250.c @@ -149,7 +149,9 @@ struct irq_info { struct list_head *head; }; -static struct irq_info irq_lists[NR_IRQS]; +static struct irq_info *irq_lists; + +DEFINE_DYN_ARRAY(irq_lists, sizeof(struct irq_info), nr_irqs, sizeof(struct irq_info), NULL); /* * Here we define the default xmit fifo size used for each type of UART. @@ -2433,7 +2435,7 @@ static void serial8250_config_port(struc 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) @@ -2964,7 +2966,7 @@ static int __init serial8250_init(void) "%d ports, IRQ sharing %sabled\n", nr_uarts, share_irqs ? "en" : "dis"); - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) spin_lock_init(&irq_lists[i].lock); ret = uart_register_driver(&serial8250_reg); Index: linux-2.6/drivers/serial/serial_core.c =================================================================== --- linux-2.6.orig/drivers/serial/serial_core.c +++ linux-2.6/drivers/serial/serial_core.c @@ -741,7 +741,7 @@ static int uart_set_info(struct uart_sta if (port->ops->verify_port) retval = port->ops->verify_port(port, &new_serial); - if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || + if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) || (new_serial.baud_base < 9600)) retval = -EINVAL; Index: linux-2.6/drivers/xen/events.c =================================================================== --- linux-2.6.orig/drivers/xen/events.c +++ linux-2.6/drivers/xen/events.c @@ -150,7 +150,7 @@ static void init_evtchn_cpu_bindings(voi #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 @@ -234,12 +234,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; } @@ -772,7 +772,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++) @@ -804,7 +804,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()); 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 @@ -503,7 +503,7 @@ static int show_stat(struct seq_file *p, 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, 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, } 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 */ 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; } Index: linux-2.6/include/asm-generic/vmlinux.lds.h =================================================================== --- linux-2.6.orig/include/asm-generic/vmlinux.lds.h +++ linux-2.6/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 \ .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__security_initcall_start) = .; \ Index: linux-2.6/include/asm-x86/irq.h =================================================================== --- linux-2.6.orig/include/asm-x86/irq.h +++ linux-2.6/include/asm-x86/irq.h @@ -10,6 +10,10 @@ #include <asm/apicdef.h> #include <asm/irq_vectors.h> +extern int nr_irqs; +extern int pin_map_size; +extern int first_free_entry; + static inline int irq_canonicalize(int irq) { return ((irq == 2) ? 9 : irq); Index: linux-2.6/include/asm-x86/irq_vectors.h =================================================================== --- linux-2.6.orig/include/asm-x86/irq_vectors.h +++ linux-2.6/include/asm-x86/irq_vectors.h @@ -113,28 +113,26 @@ # if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_PARAVIRT) || defined(CONFIG_X86_VISWS) +#ifdef CONFIG_X86_64 +# define NR_IRQS (NR_VECTORS * NR_CPUS) +#else # define NR_IRQS 224 - -# if (224 >= 32 * NR_CPUS) -# define NR_IRQ_VECTORS NR_IRQS -# else -# define NR_IRQ_VECTORS (32 * NR_CPUS) -# endif +#endif # else /* IO_APIC || PARAVIRT */ # define NR_IRQS 16 -# define NR_IRQ_VECTORS NR_IRQS # endif #else /* !VISWS && !VOYAGER */ # define NR_IRQS 224 -# define NR_IRQ_VECTORS NR_IRQS #endif /* VISWS */ +#define NR_IRQ_VECTORS NR_IRQS + /* Voyager specific defines */ /* These define the CPIs we use in linux */ #define VIC_CPI_LEVEL0 0 Index: linux-2.6/include/linux/init.h =================================================================== --- linux-2.6.orig/include/linux/init.h +++ linux-2.6/include/linux/init.h @@ -249,6 +249,29 @@ struct obs_kernel_param { /* Relies on boot_command_line being set */ void __init parse_early_param(void); + +struct dyn_array { + void **name; + unsigned long size; + unsigned int *nr; + unsigned long align; + void (*init_work)(void *); +}; +extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[]; + +#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ + static struct dyn_array __dyn_array_##nameX __initdata = \ + { .name = &nameX,\ + .size = sizeX,\ + .nr = &nrX,\ + .align = alignX,\ + .init_work = init_workX,\ + }; \ + static struct dyn_array *__dyn_array_ptr_##nameX __used \ + __attribute__((__section__(".dyn_array.init"))) = \ + &__dyn_array_##nameX + +extern void pre_alloc_dyn_array(void); #endif /* __ASSEMBLY__ */ /** Index: linux-2.6/include/linux/irq.h =================================================================== --- linux-2.6.orig/include/linux/irq.h +++ linux-2.6/include/linux/irq.h @@ -179,7 +179,7 @@ struct irq_desc { const char *name; } ____cacheline_internodealigned_in_smp; -extern struct irq_desc irq_desc[NR_IRQS]; +extern struct irq_desc *irq_desc; /* * Migration helpers for obsolete names, they will go away: Index: linux-2.6/init/main.c =================================================================== --- linux-2.6.orig/init/main.c +++ linux-2.6/init/main.c @@ -539,6 +539,26 @@ void __init __weak thread_info_cache_ini { } +void pre_alloc_dyn_array(void) +{ + unsigned long size; + struct dyn_array **daa; + + for (daa = __dyn_array_start ; daa < __dyn_array_end; daa++) { + struct dyn_array *da = *daa; + + size = da->size * (*da->nr); + print_fn_descriptor_symbol("dyna_array %s", da->name); + printk(KERN_INFO "%p name:%p size:%lx nr:%d align:%lx", + da, da->name, da->size, *da->nr, da->align); + *da->name = __alloc_bootmem_nopanic(size, da->align, 16ULL<<20); + printk(KERN_CONT " *name:%p\n", *da->name); + + if (da->init_work) + da->init_work(da); + } +} + asmlinkage void __init start_kernel(void) { char * command_line; Index: linux-2.6/kernel/irq/autoprobe.c =================================================================== --- linux-2.6.orig/kernel/irq/autoprobe.c +++ linux-2.6/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 lon int i; mask = 0; - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; unsigned int status; @@ -173,7 +173,7 @@ int probe_irq_off(unsigned long val) { int i, irq_found = 0, nr_irqs = 0; - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; unsigned int status; Index: linux-2.6/kernel/irq/chip.c =================================================================== --- linux-2.6.orig/kernel/irq/chip.c +++ linux-2.6/kernel/irq/chip.c @@ -27,7 +27,7 @@ void dynamic_irq_init(unsigned int irq) struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); return; } @@ -60,7 +60,7 @@ void dynamic_irq_cleanup(unsigned int ir struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); return; } @@ -92,7 +92,7 @@ int set_irq_chip(unsigned int irq, struc struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq); return -EINVAL; } @@ -121,7 +121,7 @@ int set_irq_type(unsigned int irq, unsig unsigned long flags; int ret = -ENXIO; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq); return -ENODEV; } @@ -148,7 +148,7 @@ int set_irq_data(unsigned int irq, void struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to install controller data for IRQ%d\n", irq); return -EINVAL; @@ -174,7 +174,7 @@ int set_irq_msi(unsigned int irq, struct struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to install msi data for IRQ%d\n", irq); return -EINVAL; @@ -200,7 +200,7 @@ int set_irq_chip_data(unsigned int irq, struct irq_desc *desc = irq_desc + irq; unsigned long flags; - if (irq >= NR_IRQS || !desc->chip) { + if (irq >= nr_irqs || !desc->chip) { printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq); return -EINVAL; } @@ -544,7 +544,7 @@ __set_irq_handler(unsigned int irq, irq_ struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to install type control for IRQ%d\n", irq); return; @@ -609,7 +609,7 @@ void __init set_irq_noprobe(unsigned int struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq); return; @@ -627,7 +627,7 @@ void __init set_irq_probe(unsigned int i struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq); return; Index: linux-2.6/kernel/irq/handle.c =================================================================== --- linux-2.6.orig/kernel/irq/handle.c +++ linux-2.6/kernel/irq/handle.c @@ -47,19 +47,33 @@ handle_bad_irq(unsigned int irq, struct * * Controller mappings for all interrupt sources: */ -struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { - [0 ... NR_IRQS-1] = { - .status = IRQ_DISABLED, - .chip = &no_irq_chip, - .handle_irq = handle_bad_irq, - .depth = 1, - .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), +static struct irq_desc irq_desc_init = { + .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 + .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); + /* * What should we do if we get a hw irq event on an illegal vector? * Each architecture has to answer this themself. @@ -265,7 +279,7 @@ void early_init_irq_lock_class(void) { int i; - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) lockdep_set_class(&irq_desc[i].lock, &irq_desc_lock_class); } Index: linux-2.6/kernel/irq/manage.c =================================================================== --- linux-2.6.orig/kernel/irq/manage.c +++ linux-2.6/kernel/irq/manage.c @@ -34,7 +34,7 @@ void synchronize_irq(unsigned int irq) struct irq_desc *desc = irq_desc + irq; unsigned int status; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; do { @@ -143,7 +143,7 @@ void disable_irq_nosync(unsigned int irq struct irq_desc *desc = irq_desc + irq; unsigned long flags; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; spin_lock_irqsave(&desc->lock, flags); @@ -171,7 +171,7 @@ void disable_irq(unsigned int irq) { struct irq_desc *desc = irq_desc + irq; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; disable_irq_nosync(irq); @@ -214,7 +214,7 @@ void enable_irq(unsigned int irq) struct irq_desc *desc = irq_desc + irq; unsigned long flags; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; spin_lock_irqsave(&desc->lock, flags); @@ -290,7 +290,7 @@ int can_request_irq(unsigned int irq, un { struct irqaction *action; - if (irq >= NR_IRQS || irq_desc[irq].status & IRQ_NOREQUEST) + if (irq >= nr_irqs || irq_desc[irq].status & IRQ_NOREQUEST) return 0; action = irq_desc[irq].action; @@ -349,7 +349,7 @@ int setup_irq(unsigned int irq, struct i int shared = 0; int ret; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return -EINVAL; if (desc->chip == &no_irq_chip) @@ -503,7 +503,7 @@ void free_irq(unsigned int irq, void *de unsigned long flags; WARN_ON(in_interrupt()); - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; desc = irq_desc + irq; @@ -617,7 +617,7 @@ int request_irq(unsigned int irq, irq_ha */ if ((irqflags & IRQF_SHARED) && !dev_id) return -EINVAL; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return -EINVAL; if (irq_desc[irq].status & IRQ_NOREQUEST) return -EINVAL; Index: linux-2.6/kernel/irq/proc.c =================================================================== --- linux-2.6.orig/kernel/irq/proc.c +++ linux-2.6/kernel/irq/proc.c @@ -234,7 +234,7 @@ void init_irq_proc(void) /* * Create entries for all existing IRQs. */ - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) register_irq_proc(i); } Index: linux-2.6/kernel/irq/resend.c =================================================================== --- linux-2.6.orig/kernel/irq/resend.c +++ linux-2.6/kernel/irq/resend.c @@ -33,8 +33,8 @@ static void resend_irqs(unsigned long ar struct irq_desc *desc; int irq; - while (!bitmap_empty(irqs_resend, NR_IRQS)) { - irq = find_first_bit(irqs_resend, NR_IRQS); + while (!bitmap_empty(irqs_resend, nr_irqs)) { + irq = find_first_bit(irqs_resend, nr_irqs); clear_bit(irq, irqs_resend); desc = irq_desc + irq; local_irq_disable(); Index: linux-2.6/kernel/irq/spurious.c =================================================================== --- linux-2.6.orig/kernel/irq/spurious.c +++ linux-2.6/kernel/irq/spurious.c @@ -91,7 +91,7 @@ static int misrouted_irq(int irq) int i; int ok = 0; - for (i = 1; i < NR_IRQS; i++) { + for (i = 1; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; if (i == irq) /* Already tried */ @@ -107,7 +107,7 @@ static int misrouted_irq(int irq) static void poll_spurious_irqs(unsigned long dummy) { int i; - for (i = 1; i < NR_IRQS; i++) { + for (i = 1; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; unsigned int status; ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: RFC [PATCH] x86: introduce nr_irqs for 64bit 2008-07-30 4:38 ` RFC [PATCH] x86: introduce nr_irqs for 64bit Yinghai Lu @ 2008-07-30 10:09 ` Ingo Molnar 2008-07-30 10:16 ` Yinghai Lu 2008-07-30 12:58 ` Mike Travis 2008-07-30 10:11 ` [PATCH] x86: introduce nr_irqs for 64bit v2 Yinghai Lu 1 sibling, 2 replies; 44+ messages in thread From: Ingo Molnar @ 2008-07-30 10:09 UTC (permalink / raw) To: Yinghai Lu Cc: Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel * Yinghai Lu <yhlu.kernel@gmail.com> wrote: > add DEFINE_DYN_ARRAY for dynamical array support > > todo: > 1. convert x86 32bit and other arch > 2. nr_irqs auto probe via acpi_oem_check? > > Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> wonderful! I have one main structural suggestion: could we please keep the NR_IRQS name, and just change it to dynamic on x86? NR_IRQS is used in 540 places in the kernel, there's no point in touching all that code. Also add an CONFIG_ARCH_HAS_DYNAMIC_NR_IRQS switch, define it in arch/x86/Kconfig and use it in include/linux/irq.h. This will create far less migration pain than the widespread rename. That will also solve the "what about the other architectures" question. Ingo ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: RFC [PATCH] x86: introduce nr_irqs for 64bit 2008-07-30 10:09 ` Ingo Molnar @ 2008-07-30 10:16 ` Yinghai Lu 2008-07-30 12:58 ` Mike Travis 1 sibling, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-30 10:16 UTC (permalink / raw) To: Ingo Molnar Cc: Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel On Wed, Jul 30, 2008 at 3:09 AM, Ingo Molnar <mingo@elte.hu> wrote: > > * Yinghai Lu <yhlu.kernel@gmail.com> wrote: > >> add DEFINE_DYN_ARRAY for dynamical array support >> >> todo: >> 1. convert x86 32bit and other arch >> 2. nr_irqs auto probe via acpi_oem_check? >> >> Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> > > wonderful! > > I have one main structural suggestion: could we please keep the NR_IRQS > name, and just change it to dynamic on x86? NR_IRQS is used in 540 > places in the kernel, there's no point in touching all that code. > > Also add an CONFIG_ARCH_HAS_DYNAMIC_NR_IRQS switch, define it in > arch/x86/Kconfig and use it in include/linux/irq.h. > > This will create far less migration pain than the widespread rename. > That will also solve the "what about the other architectures" question. just send out v2. long term, i hope to make all arch to use nr_irqs and probe it earlier. and kill NR_IRQS YH ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: RFC [PATCH] x86: introduce nr_irqs for 64bit 2008-07-30 10:09 ` Ingo Molnar 2008-07-30 10:16 ` Yinghai Lu @ 2008-07-30 12:58 ` Mike Travis 1 sibling, 0 replies; 44+ messages in thread From: Mike Travis @ 2008-07-30 12:58 UTC (permalink / raw) To: Ingo Molnar Cc: Yinghai Lu, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Andrew Morton, linux-kernel Ingo Molnar wrote: > * Yinghai Lu <yhlu.kernel@gmail.com> wrote: > >> add DEFINE_DYN_ARRAY for dynamical array support >> >> todo: >> 1. convert x86 32bit and other arch >> 2. nr_irqs auto probe via acpi_oem_check? >> >> Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> > > wonderful! > > I have one main structural suggestion: could we please keep the NR_IRQS > name, and just change it to dynamic on x86? NR_IRQS is used in 540 > places in the kernel, there's no point in touching all that code. Good thought. > > Also add an CONFIG_ARCH_HAS_DYNAMIC_NR_IRQS switch, define it in > arch/x86/Kconfig and use it in include/linux/irq.h. It could also revert DEFINE_DYN_ARRAY to a fixed array for more compact code in small machines. Thanks, Mike > > This will create far less migration pain than the widespread rename. > That will also solve the "what about the other architectures" question. > > Ingo ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH] x86: introduce nr_irqs for 64bit v2 2008-07-30 4:38 ` RFC [PATCH] x86: introduce nr_irqs for 64bit Yinghai Lu 2008-07-30 10:09 ` Ingo Molnar @ 2008-07-30 10:11 ` Yinghai Lu 2008-07-30 19:10 ` [PATCH 0/7] dyn_array support Yinghai Lu 1 sibling, 1 reply; 44+ messages in thread From: Yinghai Lu @ 2008-07-30 10:11 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel add DEFINE_DYN_ARRAY for dynamical array support v2: other platform will have nr_irqs = NR_IRQS for MAXSMP/UV: could set smaller nr_irqs in acpi_madt_oem_check in genx2_apic_uv_x Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/io_apic_32.c | 20 +++++------ arch/x86/kernel/io_apic_64.c | 57 ++++++++++++++++++++------------ 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 - arch/x86/kernel/setup.c | 8 ++++ arch/x86/kernel/vmlinux_32.lds.S | 1 arch/x86/kernel/vmlinux_64.lds.S | 3 + drivers/char/hpet.c | 2 - drivers/char/random.c | 10 ++++- drivers/char/vr41xx_giu.c | 2 - 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 - drivers/pci/intr_remapping.c | 22 ++++++------ drivers/pcmcia/at91_cf.c | 2 - drivers/pcmcia/vrc4171_card.c | 2 - drivers/rtc/rtc-vr41xx.c | 4 +- drivers/scsi/aha152x.c | 2 - drivers/serial/8250.c | 4 +- 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 - drivers/xen/events.c | 12 +++--- fs/proc/proc_misc.c | 10 ++--- include/asm-generic/vmlinux.lds.h | 7 +++ include/asm-x86/irq.h | 3 + include/asm-x86/irq_vectors.h | 14 +++---- include/linux/init.h | 23 ++++++++++++ include/linux/irq.h | 6 +++ init/main.c | 21 +++++++++++ kernel/irq/autoprobe.c | 10 ++--- kernel/irq/chip.c | 20 +++++------ kernel/irq/handle.c | 34 ++++++++++++++++++- kernel/irq/manage.c | 16 ++++---- kernel/irq/proc.c | 2 - kernel/irq/resend.c | 4 +- kernel/irq/spurious.c | 4 +- 45 files changed, 252 insertions(+), 127 deletions(-) Index: linux-2.6/arch/x86/kernel/io_apic_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/io_apic_32.c +++ linux-2.6/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 */ @@ -213,7 +214,6 @@ static void ioapic_mask_entry(int apic, */ 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) @@ -457,7 +457,7 @@ static inline void rotate_irqs_among_cpu 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 +492,7 @@ static void do_irq_balance(void) if (!cpu_online(i)) continue; package_index = CPU_TO_PACKAGEINDEX(i); - for (j = 0; j < NR_IRQS; j++) { + for (j = 0; j < nr_irqs; j++) { unsigned long value_now, delta; /* Is this an active IRQ or balancing disabled ? */ if (!irq_desc[j].action || irq_balancing_disabled(j)) @@ -587,7 +587,7 @@ tryanotherirq: */ move_this_load = 0; selected_irq = -1; - for (j = 0; j < NR_IRQS; j++) { + for (j = 0; j < nr_irqs; j++) { /* Is this an active IRQ? */ if (!irq_desc[j].action) continue; @@ -664,7 +664,7 @@ static int balanced_irq(void *unused) long time_remaining = balanced_irq_interval; /* push everything to CPU 0 to give us a starting point. */ - for (i = 0 ; i < NR_IRQS ; i++) { + for (i = 0 ; i < nr_irqs ; i++) { irq_desc[i].pending_mask = cpumask_of_cpu(0); set_pending_irq(i, cpumask_of_cpu(0)); } @@ -712,8 +712,8 @@ static int __init balanced_irq_init(void physical_balance = 1; for_each_online_cpu(i) { - irq_cpu_data[i].irq_delta = kzalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); - irq_cpu_data[i].last_irq = kzalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); + irq_cpu_data[i].irq_delta = kzalloc(sizeof(unsigned long) * nr_irqs, GFP_KERNEL); + irq_cpu_data[i].last_irq = kzalloc(sizeof(unsigned long) * nr_irqs, GFP_KERNEL); if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { printk(KERN_ERR "balanced_irq_init: out of memory"); goto failed; @@ -1445,7 +1445,7 @@ __apicdebuginit(void) print_IO_APIC(void } } printk(KERN_DEBUG "IRQ to pin mappings:\n"); - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; @@ -2009,7 +2009,7 @@ static inline void init_IO_APIC_traps(vo * Also, we've got to be careful not to trash gate * 0x80, because int 0x80 is hm, kind of importantish. ;) */ - for (irq = 0; irq < NR_IRQS ; irq++) { + for (irq = 0; irq < nr_irqs ; irq++) { if (IO_APIC_IRQ(irq) && !irq_vector[irq]) { /* * Hmm.. We don't have an entry for this, @@ -2453,7 +2453,7 @@ int create_irq(void) irq = -ENOSPC; spin_lock_irqsave(&vector_lock, flags); - for (new = (NR_IRQS - 1); new >= 0; new--) { + for (new = (nr_irqs - 1); new >= 0; new--) { if (platform_legacy_irq(new)) continue; if (irq_vector[new] != 0) Index: linux-2.6/arch/x86/kernel/io_apic_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/io_apic_64.c +++ linux-2.6/arch/x86/kernel/io_apic_64.c @@ -66,7 +66,7 @@ struct irq_cfg { }; /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ -static struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = { +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, }, @@ -85,6 +85,17 @@ static struct irq_cfg irq_cfg[NR_IRQS] _ [15] = { .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, }, }; +static struct irq_cfg *irq_cfg; + +static void __init init_work(void *data) +{ + struct dyn_array *da = data; + + memcpy(*da->name, irq_cfg_legacy, sizeof(irq_cfg_legacy)); +} + +DEFINE_DYN_ARRAY(irq_cfg, sizeof(struct irq_cfg), nr_irqs, PAGE_SIZE, init_work); + static int assign_irq_vector(int irq, cpumask_t mask); int first_system_vector = 0xfe; @@ -129,8 +140,8 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BU * 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; /* * This is performance-critical, we want to do it O(1) @@ -140,8 +151,12 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BU */ static struct irq_pin_list { - short apic, pin, next; -} irq_2_pin[PIN_MAP_SIZE]; + short apic, pin; + int next; +} *irq_2_pin; + +DEFINE_DYN_ARRAY(irq_2_pin, sizeof(struct irq_pin_list), pin_map_size, sizeof(struct irq_pin_list), NULL); + struct io_apic { unsigned int index; @@ -224,7 +239,7 @@ static inline void io_apic_sync(unsigned int pin; \ struct irq_pin_list *entry = irq_2_pin + irq; \ \ - BUG_ON(irq >= NR_IRQS); \ + BUG_ON(irq >= nr_irqs); \ for (;;) { \ unsigned int reg; \ pin = entry->pin; \ @@ -301,7 +316,7 @@ static void __target_IO_APIC_irq(unsigne int apic, pin; struct irq_pin_list *entry = irq_2_pin + irq; - BUG_ON(irq >= NR_IRQS); + BUG_ON(irq >= nr_irqs); for (;;) { unsigned int reg; apic = entry->apic; @@ -358,19 +373,19 @@ static void set_ioapic_affinity_irq(unsi * shared ISA-space IRQs, so we have to support them. We are super * fast in the common case, and fast for shared ISA-space IRQs. */ +int first_free_entry; 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; - BUG_ON(irq >= NR_IRQS); + BUG_ON(irq >= nr_irqs); while (entry->next) entry = irq_2_pin + entry->next; 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: ran out of irq_2_pin entries!"); } entry->apic = apic; @@ -634,7 +649,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, best_guess = irq; } } - BUG_ON(best_guess >= NR_IRQS); + BUG_ON(best_guess >= nr_irqs); return best_guess; } @@ -766,7 +781,7 @@ static int pin_2_irq(int idx, int apic, irq += nr_ioapic_registers[i++]; irq += pin; } - BUG_ON(irq >= NR_IRQS); + BUG_ON(irq >= nr_irqs); return irq; } @@ -788,7 +803,7 @@ static int __assign_irq_vector(int irq, int cpu; struct irq_cfg *cfg; - BUG_ON((unsigned)irq >= NR_IRQS); + BUG_ON((unsigned)irq >= nr_irqs); cfg = &irq_cfg[irq]; /* Only try and allocate irqs on cpus that are present */ @@ -862,7 +877,7 @@ static void __clear_irq_vector(int irq) cpumask_t mask; int cpu, vector; - BUG_ON((unsigned)irq >= NR_IRQS); + BUG_ON((unsigned)irq >= nr_irqs); cfg = &irq_cfg[irq]; BUG_ON(!cfg->vector); @@ -882,7 +897,7 @@ static void __setup_vector_irq(int cpu) int irq, vector; /* Mark the inuse vectors */ - for (irq = 0; irq < NR_IRQS; ++irq) { + for (irq = 0; irq < nr_irqs; ++irq) { if (!cpu_isset(cpu, irq_cfg[irq].domain)) continue; vector = irq_cfg[irq].vector; @@ -1188,7 +1203,7 @@ __apicdebuginit(void) print_IO_APIC(void } } printk(KERN_DEBUG "IRQ to pin mappings:\n"); - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; @@ -1361,7 +1376,7 @@ void __init enable_IO_APIC(void) int i, apic; unsigned long flags; - for (i = 0; i < PIN_MAP_SIZE; i++) { + for (i = 0; i < pin_map_size; i++) { irq_2_pin[i].pin = -1; irq_2_pin[i].next = 0; } @@ -1655,7 +1670,7 @@ static void ir_irq_migration(struct work { int irq; - for (irq = 0; irq < NR_IRQS; irq++) { + for (irq = 0; irq < nr_irqs; irq++) { struct irq_desc *desc = irq_desc + irq; if (desc->status & IRQ_MOVE_PENDING) { unsigned long flags; @@ -1704,7 +1719,7 @@ asmlinkage void smp_irq_move_cleanup_int struct irq_desc *desc; struct irq_cfg *cfg; irq = __get_cpu_var(vector_irq)[vector]; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) continue; desc = irq_desc + irq; @@ -1862,7 +1877,7 @@ static inline void init_IO_APIC_traps(vo * Also, we've got to be careful not to trash gate * 0x80, because int 0x80 is hm, kind of importantish. ;) */ - for (irq = 0; irq < NR_IRQS ; irq++) { + for (irq = 0; irq < nr_irqs ; irq++) { if (IO_APIC_IRQ(irq) && !irq_cfg[irq].vector) { /* * Hmm.. We don't have an entry for this, @@ -2276,7 +2291,7 @@ int create_irq(void) irq = -ENOSPC; spin_lock_irqsave(&vector_lock, flags); - for (new = (NR_IRQS - 1); new >= 0; new--) { + for (new = (nr_irqs - 1); new >= 0; new--) { if (platform_legacy_irq(new)) continue; if (irq_cfg[new].vector != 0) Index: linux-2.6/arch/x86/kernel/irq_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/irq_32.c +++ linux-2.6/arch/x86/kernel/irq_32.c @@ -226,7 +226,7 @@ unsigned int do_IRQ(struct pt_regs *regs int overflow, irq = ~regs->orig_ax; struct irq_desc *desc = irq_desc + irq; - if (unlikely((unsigned)irq >= NR_IRQS)) { + if (unlikely((unsigned)irq >= nr_irqs)) { printk(KERN_EMERG "%s: cannot handle IRQ %d\n", __func__, irq); BUG(); @@ -271,7 +271,7 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); } - if (i < NR_IRQS) { + if (i < nr_irqs) { unsigned any_count = 0; spin_lock_irqsave(&irq_desc[i].lock, flags); @@ -303,7 +303,7 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { + } else if (i == nr_irqs) { seq_printf(p, "NMI: "); for_each_online_cpu(j) seq_printf(p, "%10u ", nmi_count(j)); @@ -396,7 +396,7 @@ void fixup_irqs(cpumask_t map) unsigned int irq; static int warned; - for (irq = 0; irq < NR_IRQS; irq++) { + for (irq = 0; irq < nr_irqs; irq++) { cpumask_t mask; if (irq == 2) continue; Index: linux-2.6/arch/x86/kernel/irq_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/irq_64.c +++ linux-2.6/arch/x86/kernel/irq_64.c @@ -81,7 +81,7 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); } - if (i < NR_IRQS) { + if (i < nr_irqs) { unsigned any_count = 0; spin_lock_irqsave(&irq_desc[i].lock, flags); @@ -112,7 +112,7 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { + } else if (i == nr_irqs) { seq_printf(p, "NMI: "); for_each_online_cpu(j) seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count); @@ -201,7 +201,7 @@ asmlinkage unsigned int do_IRQ(struct pt stack_overflow_check(regs); #endif - if (likely(irq < NR_IRQS)) + if (likely(irq < nr_irqs)) generic_handle_irq(irq); else { if (!disable_apic) @@ -224,7 +224,7 @@ void fixup_irqs(cpumask_t map) unsigned int irq; static int warned; - for (irq = 0; irq < NR_IRQS; irq++) { + for (irq = 0; irq < nr_irqs; irq++) { cpumask_t mask; int break_affinity = 0; int set_affinity = 1; Index: linux-2.6/arch/x86/kernel/irqinit_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/irqinit_32.c +++ linux-2.6/arch/x86/kernel/irqinit_32.c @@ -91,7 +91,7 @@ void __init native_init_IRQ(void) */ for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) { int vector = FIRST_EXTERNAL_VECTOR + i; - if (i >= NR_IRQS) + if (i >= nr_irqs) break; /* SYSCALL_VECTOR was reserved in trap_init. */ if (!test_bit(vector, used_vectors)) Index: linux-2.6/arch/x86/kernel/irqinit_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/irqinit_64.c +++ linux-2.6/arch/x86/kernel/irqinit_64.c @@ -142,7 +142,7 @@ static void __init init_ISA_irqs (void) init_bsp_APIC(); init_8259A(0); - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; Index: linux-2.6/arch/x86/kernel/setup.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup.c +++ linux-2.6/arch/x86/kernel/setup.c @@ -856,7 +856,15 @@ void __init setup_arch(char **cmdline_p) #endif prefill_possible_map(); + #ifdef CONFIG_X86_64 + /* need to wait for nr_cpu_ids settle down */ + if (nr_irqs == NR_IRQS) + nr_irqs = 32 * nr_cpu_ids + 224; + pin_map_size = nr_irqs * 2; + first_free_entry = nr_irqs; + printk(KERN_INFO "nr_irqs: %d\n", nr_irqs); + pre_alloc_dyn_array(); init_cpu_to_node(); #endif Index: linux-2.6/arch/x86/kernel/vmlinux_32.lds.S =================================================================== --- linux-2.6.orig/arch/x86/kernel/vmlinux_32.lds.S +++ linux-2.6/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) { Index: linux-2.6/arch/x86/kernel/vmlinux_64.lds.S =================================================================== --- linux-2.6.orig/arch/x86/kernel/vmlinux_64.lds.S +++ linux-2.6/arch/x86/kernel/vmlinux_64.lds.S @@ -174,6 +174,9 @@ SECTIONS *(.x86cpuvendor.init) } __x86cpuvendor_end = .; + + DYN_ARRAY_INIT(8) + SECURITY_INIT . = ALIGN(8); Index: linux-2.6/drivers/char/hpet.c =================================================================== --- linux-2.6.orig/drivers/char/hpet.c +++ linux-2.6/drivers/char/hpet.c @@ -222,7 +222,7 @@ static void hpet_timer_set_irq(struct hp 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; } Index: linux-2.6/drivers/char/random.c =================================================================== --- linux-2.6.orig/drivers/char/random.c +++ linux-2.6/drivers/char/random.c @@ -558,7 +558,13 @@ struct timer_rand_state { }; static struct timer_rand_state input_timer_state; + +#ifdef CONFIG_X86_64 +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 @@ -647,7 +653,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 +917,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; /* Index: linux-2.6/drivers/char/vr41xx_giu.c =================================================================== --- linux-2.6.orig/drivers/char/vr41xx_giu.c +++ linux-2.6/drivers/char/vr41xx_giu.c @@ -641,7 +641,7 @@ static int __devinit giu_probe(struct pl } 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); Index: linux-2.6/drivers/net/3c59x.c =================================================================== --- linux-2.6.orig/drivers/net/3c59x.c +++ linux-2.6/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(struc 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); Index: linux-2.6/drivers/net/hamradio/baycom_ser_fdx.c =================================================================== --- linux-2.6.orig/drivers/net/hamradio/baycom_ser_fdx.c +++ linux-2.6/drivers/net/hamradio/baycom_ser_fdx.c @@ -416,10 +416,10 @@ static int ser12_open(struct net_device 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) { Index: linux-2.6/drivers/net/hamradio/scc.c =================================================================== --- linux-2.6.orig/drivers/net/hamradio/scc.c +++ linux-2.6/drivers/net/hamradio/scc.c @@ -1465,7 +1465,7 @@ static void z8530_init(void) printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2); flag=" "; - for (k = 0; k < NR_IRQS; k++) + for (k = 0; k < nr_irqs; k++) if (Ivec[k].used) { printk("%s%d", flag, k); @@ -1728,7 +1728,7 @@ static int scc_net_ioctl(struct net_devi if (hwcfg.irq == 2) hwcfg.irq = 9; - if (hwcfg.irq < 0 || hwcfg.irq >= NR_IRQS) + if (hwcfg.irq < 0 || hwcfg.irq >= nr_irqs) return -EINVAL; if (!Ivec[hwcfg.irq].used && hwcfg.irq) @@ -2148,7 +2148,7 @@ static void __exit scc_cleanup_driver(vo } /* To unload the port must be closed so no real IRQ pending */ - for (k=0; k < NR_IRQS ; k++) + for (k=0; k < nr_irqs ; k++) if (Ivec[k].used) free_irq(k, NULL); local_irq_enable(); Index: linux-2.6/drivers/net/wan/sbni.c =================================================================== --- linux-2.6.orig/drivers/net/wan/sbni.c +++ linux-2.6/drivers/net/wan/sbni.c @@ -318,7 +318,7 @@ sbni_pci_probe( struct net_device *dev continue; } - if( pci_irq_line <= 0 || pci_irq_line >= NR_IRQS ) + if( pci_irq_line <= 0 || pci_irq_line >= nr_irqs ) printk( KERN_WARNING " WARNING: The PCI BIOS assigned " "this PCI card to IRQ %d, which is unlikely " "to work!.\n" Index: linux-2.6/drivers/pci/intr_remapping.c =================================================================== --- linux-2.6.orig/drivers/pci/intr_remapping.c +++ linux-2.6/drivers/pci/intr_remapping.c @@ -11,18 +11,20 @@ static struct ioapic_scope ir_ioapic[MAX static int ir_ioapic_num; int intr_remapping_enabled; -static struct { +static struct irq_2_iommu { struct intel_iommu *iommu; u16 irte_index; u16 sub_handle; u8 irte_mask; -} irq_2_iommu[NR_IRQS]; +} *irq_2_iommu; + +DEFINE_DYN_ARRAY(irq_2_iommu, sizeof(struct irq_2_iommu), nr_irqs, PAGE_SIZE, NULL); 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 +37,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 +128,7 @@ int map_irq_to_irte_handle(int irq, u16 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 +142,7 @@ int map_irq_to_irte_handle(int irq, u16 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 +160,7 @@ int set_irte_irq(int irq, struct intel_i 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 +182,7 @@ int modify_irte(int irq, struct irte *ir 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 +207,7 @@ int flush_irte(int irq) 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; } @@ -248,7 +250,7 @@ int free_irte(int irq) 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; } Index: linux-2.6/drivers/pcmcia/at91_cf.c =================================================================== --- linux-2.6.orig/drivers/pcmcia/at91_cf.c +++ linux-2.6/drivers/pcmcia/at91_cf.c @@ -273,7 +273,7 @@ static int __init at91_cf_probe(struct p 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) Index: linux-2.6/drivers/pcmcia/vrc4171_card.c =================================================================== --- linux-2.6.orig/drivers/pcmcia/vrc4171_card.c +++ linux-2.6/drivers/pcmcia/vrc4171_card.c @@ -639,7 +639,7 @@ static int __devinit vrc4171_card_setup( 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 != ',') Index: linux-2.6/drivers/rtc/rtc-vr41xx.c =================================================================== --- linux-2.6.orig/drivers/rtc/rtc-vr41xx.c +++ linux-2.6/drivers/rtc/rtc-vr41xx.c @@ -360,7 +360,7 @@ static int __devinit rtc_probe(struct pl 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 pl 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, Index: linux-2.6/drivers/scsi/aha152x.c =================================================================== --- linux-2.6.orig/drivers/scsi/aha152x.c +++ linux-2.6/drivers/scsi/aha152x.c @@ -337,7 +337,7 @@ CMD_INC_RESID(struct scsi_cmnd *cmd, int #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 Index: linux-2.6/drivers/serial/8250.c =================================================================== --- linux-2.6.orig/drivers/serial/8250.c +++ linux-2.6/drivers/serial/8250.c @@ -2433,7 +2433,7 @@ static void serial8250_config_port(struc 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) @@ -2964,7 +2964,7 @@ static int __init serial8250_init(void) "%d ports, IRQ sharing %sabled\n", nr_uarts, share_irqs ? "en" : "dis"); - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) spin_lock_init(&irq_lists[i].lock); ret = uart_register_driver(&serial8250_reg); Index: linux-2.6/drivers/serial/amba-pl010.c =================================================================== --- linux-2.6.orig/drivers/serial/amba-pl010.c +++ linux-2.6/drivers/serial/amba-pl010.c @@ -512,7 +512,7 @@ static int pl010_verify_port(struct uart 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; Index: linux-2.6/drivers/serial/amba-pl011.c =================================================================== --- linux-2.6.orig/drivers/serial/amba-pl011.c +++ linux-2.6/drivers/serial/amba-pl011.c @@ -572,7 +572,7 @@ static int pl010_verify_port(struct uart 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; Index: linux-2.6/drivers/serial/cpm_uart/cpm_uart_core.c =================================================================== --- linux-2.6.orig/drivers/serial/cpm_uart/cpm_uart_core.c +++ linux-2.6/drivers/serial/cpm_uart/cpm_uart_core.c @@ -589,7 +589,7 @@ static int cpm_uart_verify_port(struct u if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) 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; Index: linux-2.6/drivers/serial/m32r_sio.c =================================================================== --- linux-2.6.orig/drivers/serial/m32r_sio.c +++ linux-2.6/drivers/serial/m32r_sio.c @@ -922,7 +922,7 @@ static void m32r_sio_config_port(struct static int m32r_sio_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)) return -EINVAL; @@ -1162,7 +1162,7 @@ static int __init m32r_sio_init(void) printk(KERN_INFO "Serial: M32R SIO driver\n"); - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) spin_lock_init(&irq_lists[i].lock); ret = uart_register_driver(&m32r_sio_reg); Index: linux-2.6/drivers/serial/serial_core.c =================================================================== --- linux-2.6.orig/drivers/serial/serial_core.c +++ linux-2.6/drivers/serial/serial_core.c @@ -741,7 +741,7 @@ static int uart_set_info(struct uart_sta if (port->ops->verify_port) retval = port->ops->verify_port(port, &new_serial); - if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || + if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) || (new_serial.baud_base < 9600)) retval = -EINVAL; Index: linux-2.6/drivers/serial/serial_lh7a40x.c =================================================================== --- linux-2.6.orig/drivers/serial/serial_lh7a40x.c +++ linux-2.6/drivers/serial/serial_lh7a40x.c @@ -460,7 +460,7 @@ static int lh7a40xuart_verify_port (stru if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X) 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) /* *** FIXME: is this true? */ ret = -EINVAL; Index: linux-2.6/drivers/serial/sh-sci.c =================================================================== --- linux-2.6.orig/drivers/serial/sh-sci.c +++ linux-2.6/drivers/serial/sh-sci.c @@ -1157,7 +1157,7 @@ static int sci_verify_port(struct uart_p { struct sci_port *s = &sci_ports[port->line]; - if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > NR_IRQS) + if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs) return -EINVAL; if (ser->baud_base < 2400) /* No paper tape reader for Mitch.. */ Index: linux-2.6/drivers/serial/ucc_uart.c =================================================================== --- linux-2.6.orig/drivers/serial/ucc_uart.c +++ linux-2.6/drivers/serial/ucc_uart.c @@ -1066,7 +1066,7 @@ static int qe_uart_verify_port(struct ua if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) return -EINVAL; - if (ser->irq < 0 || ser->irq >= NR_IRQS) + if (ser->irq < 0 || ser->irq >= nr_irqs) return -EINVAL; if (ser->baud_base < 9600) Index: linux-2.6/drivers/xen/events.c =================================================================== --- linux-2.6.orig/drivers/xen/events.c +++ linux-2.6/drivers/xen/events.c @@ -150,7 +150,7 @@ static void init_evtchn_cpu_bindings(voi #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 @@ -234,12 +234,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; } @@ -772,7 +772,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++) @@ -804,7 +804,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()); 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 @@ -503,7 +503,7 @@ static int show_stat(struct seq_file *p, 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, 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, } 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 */ 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; } Index: linux-2.6/include/asm-generic/vmlinux.lds.h =================================================================== --- linux-2.6.orig/include/asm-generic/vmlinux.lds.h +++ linux-2.6/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 \ .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__security_initcall_start) = .; \ Index: linux-2.6/include/asm-x86/irq.h =================================================================== --- linux-2.6.orig/include/asm-x86/irq.h +++ linux-2.6/include/asm-x86/irq.h @@ -10,6 +10,9 @@ #include <asm/apicdef.h> #include <asm/irq_vectors.h> +extern int pin_map_size; +extern int first_free_entry; + static inline int irq_canonicalize(int irq) { return ((irq == 2) ? 9 : irq); Index: linux-2.6/include/asm-x86/irq_vectors.h =================================================================== --- linux-2.6.orig/include/asm-x86/irq_vectors.h +++ linux-2.6/include/asm-x86/irq_vectors.h @@ -113,28 +113,26 @@ # if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_PARAVIRT) || defined(CONFIG_X86_VISWS) +#ifdef CONFIG_X86_64 +# define NR_IRQS (32 * NR_CPUS + 224) +#else # define NR_IRQS 224 - -# if (224 >= 32 * NR_CPUS) -# define NR_IRQ_VECTORS NR_IRQS -# else -# define NR_IRQ_VECTORS (32 * NR_CPUS) -# endif +#endif # else /* IO_APIC || PARAVIRT */ # define NR_IRQS 16 -# define NR_IRQ_VECTORS NR_IRQS # endif #else /* !VISWS && !VOYAGER */ # define NR_IRQS 224 -# define NR_IRQ_VECTORS NR_IRQS #endif /* VISWS */ +#define NR_IRQ_VECTORS NR_IRQS + /* Voyager specific defines */ /* These define the CPIs we use in linux */ #define VIC_CPI_LEVEL0 0 Index: linux-2.6/include/linux/init.h =================================================================== --- linux-2.6.orig/include/linux/init.h +++ linux-2.6/include/linux/init.h @@ -249,6 +249,29 @@ struct obs_kernel_param { /* Relies on boot_command_line being set */ void __init parse_early_param(void); + +struct dyn_array { + void **name; + unsigned long size; + unsigned int *nr; + unsigned long align; + void (*init_work)(void *); +}; +extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[]; + +#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ + static struct dyn_array __dyn_array_##nameX __initdata = \ + { .name = (void **)&nameX,\ + .size = sizeX,\ + .nr = &nrX,\ + .align = alignX,\ + .init_work = init_workX,\ + }; \ + static struct dyn_array *__dyn_array_ptr_##nameX __used \ + __attribute__((__section__(".dyn_array.init"))) = \ + &__dyn_array_##nameX + +extern void pre_alloc_dyn_array(void); #endif /* __ASSEMBLY__ */ /** Index: linux-2.6/include/linux/irq.h =================================================================== --- linux-2.6.orig/include/linux/irq.h +++ linux-2.6/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); @@ -179,7 +181,11 @@ struct irq_desc { const char *name; } ____cacheline_internodealigned_in_smp; +#ifdef CONFIG_X86_64 +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: Index: linux-2.6/init/main.c =================================================================== --- linux-2.6.orig/init/main.c +++ linux-2.6/init/main.c @@ -539,6 +539,27 @@ void __init __weak thread_info_cache_ini { } +void pre_alloc_dyn_array(void) +{ + unsigned long size, phys = 0; + struct dyn_array **daa; + + for (daa = __dyn_array_start ; daa < __dyn_array_end; daa++) { + struct dyn_array *da = *daa; + + size = da->size * (*da->nr); + print_fn_descriptor_symbol("dyna_array %s ", da->name); + printk(KERN_CONT "size:%#lx nr:%d align:%#lx", + da->size, *da->nr, da->align); + *da->name = __alloc_bootmem_nopanic(size, da->align, phys); + phys = virt_to_phys(*da->name); + printk(KERN_CONT " ==> [%#lx - %#lx]\n", phys, phys + size); + + if (da->init_work) + da->init_work(da); + } +} + asmlinkage void __init start_kernel(void) { char * command_line; Index: linux-2.6/kernel/irq/autoprobe.c =================================================================== --- linux-2.6.orig/kernel/irq/autoprobe.c +++ linux-2.6/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 lon int i; mask = 0; - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; unsigned int status; @@ -173,7 +173,7 @@ int probe_irq_off(unsigned long val) { int i, irq_found = 0, nr_irqs = 0; - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; unsigned int status; Index: linux-2.6/kernel/irq/chip.c =================================================================== --- linux-2.6.orig/kernel/irq/chip.c +++ linux-2.6/kernel/irq/chip.c @@ -27,7 +27,7 @@ void dynamic_irq_init(unsigned int irq) struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); return; } @@ -60,7 +60,7 @@ void dynamic_irq_cleanup(unsigned int ir struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); return; } @@ -92,7 +92,7 @@ int set_irq_chip(unsigned int irq, struc struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq); return -EINVAL; } @@ -121,7 +121,7 @@ int set_irq_type(unsigned int irq, unsig unsigned long flags; int ret = -ENXIO; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq); return -ENODEV; } @@ -148,7 +148,7 @@ int set_irq_data(unsigned int irq, void struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to install controller data for IRQ%d\n", irq); return -EINVAL; @@ -174,7 +174,7 @@ int set_irq_msi(unsigned int irq, struct struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to install msi data for IRQ%d\n", irq); return -EINVAL; @@ -200,7 +200,7 @@ int set_irq_chip_data(unsigned int irq, struct irq_desc *desc = irq_desc + irq; unsigned long flags; - if (irq >= NR_IRQS || !desc->chip) { + if (irq >= nr_irqs || !desc->chip) { printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq); return -EINVAL; } @@ -544,7 +544,7 @@ __set_irq_handler(unsigned int irq, irq_ struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to install type control for IRQ%d\n", irq); return; @@ -609,7 +609,7 @@ void __init set_irq_noprobe(unsigned int struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq); return; @@ -627,7 +627,7 @@ void __init set_irq_probe(unsigned int i struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq); return; 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,37 @@ handle_bad_irq(unsigned int irq, struct * * Controller mappings for all interrupt sources: */ +int nr_irqs = NR_IRQS; + +#ifdef CONFIG_X86_64 +static struct irq_desc irq_desc_init = { + .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; + 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, @@ -59,6 +90,7 @@ struct irq_desc irq_desc[NR_IRQS] __cach #endif } }; +#endif /* * What should we do if we get a hw irq event on an illegal vector? @@ -265,7 +297,7 @@ void early_init_irq_lock_class(void) { int i; - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) lockdep_set_class(&irq_desc[i].lock, &irq_desc_lock_class); } Index: linux-2.6/kernel/irq/manage.c =================================================================== --- linux-2.6.orig/kernel/irq/manage.c +++ linux-2.6/kernel/irq/manage.c @@ -34,7 +34,7 @@ void synchronize_irq(unsigned int irq) struct irq_desc *desc = irq_desc + irq; unsigned int status; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; do { @@ -143,7 +143,7 @@ void disable_irq_nosync(unsigned int irq struct irq_desc *desc = irq_desc + irq; unsigned long flags; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; spin_lock_irqsave(&desc->lock, flags); @@ -171,7 +171,7 @@ void disable_irq(unsigned int irq) { struct irq_desc *desc = irq_desc + irq; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; disable_irq_nosync(irq); @@ -214,7 +214,7 @@ void enable_irq(unsigned int irq) struct irq_desc *desc = irq_desc + irq; unsigned long flags; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; spin_lock_irqsave(&desc->lock, flags); @@ -290,7 +290,7 @@ int can_request_irq(unsigned int irq, un { struct irqaction *action; - if (irq >= NR_IRQS || irq_desc[irq].status & IRQ_NOREQUEST) + if (irq >= nr_irqs || irq_desc[irq].status & IRQ_NOREQUEST) return 0; action = irq_desc[irq].action; @@ -349,7 +349,7 @@ int setup_irq(unsigned int irq, struct i int shared = 0; int ret; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return -EINVAL; if (desc->chip == &no_irq_chip) @@ -503,7 +503,7 @@ void free_irq(unsigned int irq, void *de unsigned long flags; WARN_ON(in_interrupt()); - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; desc = irq_desc + irq; @@ -617,7 +617,7 @@ int request_irq(unsigned int irq, irq_ha */ if ((irqflags & IRQF_SHARED) && !dev_id) return -EINVAL; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return -EINVAL; if (irq_desc[irq].status & IRQ_NOREQUEST) return -EINVAL; Index: linux-2.6/kernel/irq/proc.c =================================================================== --- linux-2.6.orig/kernel/irq/proc.c +++ linux-2.6/kernel/irq/proc.c @@ -234,7 +234,7 @@ void init_irq_proc(void) /* * Create entries for all existing IRQs. */ - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) register_irq_proc(i); } Index: linux-2.6/kernel/irq/resend.c =================================================================== --- linux-2.6.orig/kernel/irq/resend.c +++ linux-2.6/kernel/irq/resend.c @@ -33,8 +33,8 @@ static void resend_irqs(unsigned long ar struct irq_desc *desc; int irq; - while (!bitmap_empty(irqs_resend, NR_IRQS)) { - irq = find_first_bit(irqs_resend, NR_IRQS); + while (!bitmap_empty(irqs_resend, nr_irqs)) { + irq = find_first_bit(irqs_resend, nr_irqs); clear_bit(irq, irqs_resend); desc = irq_desc + irq; local_irq_disable(); Index: linux-2.6/kernel/irq/spurious.c =================================================================== --- linux-2.6.orig/kernel/irq/spurious.c +++ linux-2.6/kernel/irq/spurious.c @@ -91,7 +91,7 @@ static int misrouted_irq(int irq) int i; int ok = 0; - for (i = 1; i < NR_IRQS; i++) { + for (i = 1; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; if (i == irq) /* Already tried */ @@ -107,7 +107,7 @@ static int misrouted_irq(int irq) static void poll_spurious_irqs(unsigned long dummy) { int i; - for (i = 1; i < NR_IRQS; i++) { + for (i = 1; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; unsigned int status; ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 0/7] dyn_array support 2008-07-30 10:11 ` [PATCH] x86: introduce nr_irqs for 64bit v2 Yinghai Lu @ 2008-07-30 19:10 ` Yinghai Lu 2008-07-30 19:13 ` [PATCH 2/7] x86: introduce nr_irqs for 64bit v3 Yinghai Lu ` (8 more replies) 0 siblings, 9 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-30 19:10 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel please check the patches adding dyn_array and nr_irqs Thanks YH ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 2/7] x86: introduce nr_irqs for 64bit v3 2008-07-30 19:10 ` [PATCH 0/7] dyn_array support Yinghai Lu @ 2008-07-30 19:13 ` Yinghai Lu 2008-07-30 19:16 ` [PATCH 5/7] pci: make irq2_iommu to use dyn_array Yinghai Lu ` (7 subsequent siblings) 8 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-30 19:13 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel add DEFINE_DYN_ARRAY for dynamical array support v2: other platform will have nr_irqs = NR_IRQS for MAXSMP/UV: could set smaller nr_irqs in acpi_madt_oem_check in genx2_apic_uv_x v3: seperate DYN_ARRAY and enabling to x86_64 to following patches 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 - drivers/char/hpet.c | 2 - drivers/char/random.c | 4 +-- drivers/char/vr41xx_giu.c | 2 - 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 - drivers/pci/intr_remapping.c | 16 +++++++-------- drivers/pcmcia/at91_cf.c | 2 - drivers/pcmcia/vrc4171_card.c | 2 - drivers/rtc/rtc-vr41xx.c | 4 +-- drivers/scsi/aha152x.c | 2 - drivers/serial/8250.c | 4 +-- 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 - drivers/xen/events.c | 12 +++++------ fs/proc/proc_misc.c | 10 ++++----- include/asm-x86/irq.h | 3 ++ 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 +-- 38 files changed, 123 insertions(+), 114 deletions(-) Index: linux-2.6/arch/x86/kernel/io_apic_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/io_apic_32.c +++ linux-2.6/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 __initdat #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, */ 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 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_cpu 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 @@ static void do_irq_balance(void) if (!cpu_online(i)) continue; package_index = CPU_TO_PACKAGEINDEX(i); - for (j = 0; j < NR_IRQS; j++) { + for (j = 0; j < nr_irqs; j++) { unsigned long value_now, delta; /* Is this an active IRQ or balancing disabled ? */ if (!irq_desc[j].action || irq_balancing_disabled(j)) @@ -587,7 +589,7 @@ tryanotherirq: */ move_this_load = 0; selected_irq = -1; - for (j = 0; j < NR_IRQS; j++) { + for (j = 0; j < nr_irqs; j++) { /* Is this an active IRQ? */ if (!irq_desc[j].action) continue; @@ -664,7 +666,7 @@ static int balanced_irq(void *unused) long time_remaining = balanced_irq_interval; /* push everything to CPU 0 to give us a starting point. */ - for (i = 0 ; i < NR_IRQS ; i++) { + for (i = 0 ; i < nr_irqs ; i++) { irq_desc[i].pending_mask = cpumask_of_cpu(0); set_pending_irq(i, cpumask_of_cpu(0)); } @@ -712,8 +714,8 @@ static int __init balanced_irq_init(void physical_balance = 1; for_each_online_cpu(i) { - irq_cpu_data[i].irq_delta = kzalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); - irq_cpu_data[i].last_irq = kzalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); + irq_cpu_data[i].irq_delta = kzalloc(sizeof(unsigned long) * nr_irqs, GFP_KERNEL); + irq_cpu_data[i].last_irq = kzalloc(sizeof(unsigned long) * nr_irqs, GFP_KERNEL); if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { printk(KERN_ERR "balanced_irq_init: out of memory"); goto failed; @@ -1445,7 +1447,7 @@ __apicdebuginit(void) print_IO_APIC(void } } printk(KERN_DEBUG "IRQ to pin mappings:\n"); - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; @@ -1625,7 +1627,7 @@ static void __init enable_IO_APIC(void) int i, apic; unsigned long flags; - for (i = 0; i < PIN_MAP_SIZE; i++) { + for (i = 0; i < pin_map_size; i++) { irq_2_pin[i].pin = -1; irq_2_pin[i].next = 0; } @@ -2009,7 +2011,7 @@ static inline void init_IO_APIC_traps(vo * Also, we've got to be careful not to trash gate * 0x80, because int 0x80 is hm, kind of importantish. ;) */ - for (irq = 0; irq < NR_IRQS ; irq++) { + for (irq = 0; irq < nr_irqs ; irq++) { if (IO_APIC_IRQ(irq) && !irq_vector[irq]) { /* * Hmm.. We don't have an entry for this, @@ -2453,7 +2455,7 @@ int create_irq(void) irq = -ENOSPC; spin_lock_irqsave(&vector_lock, flags); - for (new = (NR_IRQS - 1); new >= 0; new--) { + for (new = (nr_irqs - 1); new >= 0; new--) { if (platform_legacy_irq(new)) continue; if (irq_vector[new] != 0) Index: linux-2.6/arch/x86/kernel/io_apic_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/io_apic_64.c +++ linux-2.6/arch/x86/kernel/io_apic_64.c @@ -132,6 +132,7 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BU #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) * @@ -224,7 +225,7 @@ static inline void io_apic_sync(unsigned int pin; \ struct irq_pin_list *entry = irq_2_pin + irq; \ \ - BUG_ON(irq >= NR_IRQS); \ + BUG_ON(irq >= nr_irqs); \ for (;;) { \ unsigned int reg; \ pin = entry->pin; \ @@ -301,7 +302,7 @@ static void __target_IO_APIC_irq(unsigne int apic, pin; struct irq_pin_list *entry = irq_2_pin + irq; - BUG_ON(irq >= NR_IRQS); + BUG_ON(irq >= nr_irqs); for (;;) { unsigned int reg; apic = entry->apic; @@ -358,19 +359,19 @@ static void set_ioapic_affinity_irq(unsi * shared ISA-space IRQs, so we have to support them. We are super * fast in the common case, and fast for shared ISA-space IRQs. */ +int first_free_entry = NR_IRQS; 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; - BUG_ON(irq >= NR_IRQS); + BUG_ON(irq >= nr_irqs); while (entry->next) entry = irq_2_pin + entry->next; 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: ran out of irq_2_pin entries!"); } entry->apic = apic; @@ -634,7 +635,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, best_guess = irq; } } - BUG_ON(best_guess >= NR_IRQS); + BUG_ON(best_guess >= nr_irqs); return best_guess; } @@ -766,7 +767,7 @@ static int pin_2_irq(int idx, int apic, irq += nr_ioapic_registers[i++]; irq += pin; } - BUG_ON(irq >= NR_IRQS); + BUG_ON(irq >= nr_irqs); return irq; } @@ -788,7 +789,7 @@ static int __assign_irq_vector(int irq, int cpu; struct irq_cfg *cfg; - BUG_ON((unsigned)irq >= NR_IRQS); + BUG_ON((unsigned)irq >= nr_irqs); cfg = &irq_cfg[irq]; /* Only try and allocate irqs on cpus that are present */ @@ -862,7 +863,7 @@ static void __clear_irq_vector(int irq) cpumask_t mask; int cpu, vector; - BUG_ON((unsigned)irq >= NR_IRQS); + BUG_ON((unsigned)irq >= nr_irqs); cfg = &irq_cfg[irq]; BUG_ON(!cfg->vector); @@ -882,7 +883,7 @@ static void __setup_vector_irq(int cpu) int irq, vector; /* Mark the inuse vectors */ - for (irq = 0; irq < NR_IRQS; ++irq) { + for (irq = 0; irq < nr_irqs; ++irq) { if (!cpu_isset(cpu, irq_cfg[irq].domain)) continue; vector = irq_cfg[irq].vector; @@ -1188,7 +1189,7 @@ __apicdebuginit(void) print_IO_APIC(void } } printk(KERN_DEBUG "IRQ to pin mappings:\n"); - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; @@ -1361,7 +1362,7 @@ void __init enable_IO_APIC(void) int i, apic; unsigned long flags; - for (i = 0; i < PIN_MAP_SIZE; i++) { + for (i = 0; i < pin_map_size; i++) { irq_2_pin[i].pin = -1; irq_2_pin[i].next = 0; } @@ -1655,7 +1656,7 @@ static void ir_irq_migration(struct work { int irq; - for (irq = 0; irq < NR_IRQS; irq++) { + for (irq = 0; irq < nr_irqs; irq++) { struct irq_desc *desc = irq_desc + irq; if (desc->status & IRQ_MOVE_PENDING) { unsigned long flags; @@ -1704,7 +1705,7 @@ asmlinkage void smp_irq_move_cleanup_int struct irq_desc *desc; struct irq_cfg *cfg; irq = __get_cpu_var(vector_irq)[vector]; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) continue; desc = irq_desc + irq; @@ -1862,7 +1863,7 @@ static inline void init_IO_APIC_traps(vo * Also, we've got to be careful not to trash gate * 0x80, because int 0x80 is hm, kind of importantish. ;) */ - for (irq = 0; irq < NR_IRQS ; irq++) { + for (irq = 0; irq < nr_irqs ; irq++) { if (IO_APIC_IRQ(irq) && !irq_cfg[irq].vector) { /* * Hmm.. We don't have an entry for this, @@ -2276,7 +2277,7 @@ int create_irq(void) irq = -ENOSPC; spin_lock_irqsave(&vector_lock, flags); - for (new = (NR_IRQS - 1); new >= 0; new--) { + for (new = (nr_irqs - 1); new >= 0; new--) { if (platform_legacy_irq(new)) continue; if (irq_cfg[new].vector != 0) Index: linux-2.6/arch/x86/kernel/irq_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/irq_32.c +++ linux-2.6/arch/x86/kernel/irq_32.c @@ -226,7 +226,7 @@ unsigned int do_IRQ(struct pt_regs *regs int overflow, irq = ~regs->orig_ax; struct irq_desc *desc = irq_desc + irq; - if (unlikely((unsigned)irq >= NR_IRQS)) { + if (unlikely((unsigned)irq >= nr_irqs)) { printk(KERN_EMERG "%s: cannot handle IRQ %d\n", __func__, irq); BUG(); @@ -271,7 +271,7 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); } - if (i < NR_IRQS) { + if (i < nr_irqs) { unsigned any_count = 0; spin_lock_irqsave(&irq_desc[i].lock, flags); @@ -303,7 +303,7 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { + } else if (i == nr_irqs) { seq_printf(p, "NMI: "); for_each_online_cpu(j) seq_printf(p, "%10u ", nmi_count(j)); @@ -396,7 +396,7 @@ void fixup_irqs(cpumask_t map) unsigned int irq; static int warned; - for (irq = 0; irq < NR_IRQS; irq++) { + for (irq = 0; irq < nr_irqs; irq++) { cpumask_t mask; if (irq == 2) continue; Index: linux-2.6/arch/x86/kernel/irq_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/irq_64.c +++ linux-2.6/arch/x86/kernel/irq_64.c @@ -81,7 +81,7 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); } - if (i < NR_IRQS) { + if (i < nr_irqs) { unsigned any_count = 0; spin_lock_irqsave(&irq_desc[i].lock, flags); @@ -112,7 +112,7 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { + } else if (i == nr_irqs) { seq_printf(p, "NMI: "); for_each_online_cpu(j) seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count); @@ -201,7 +201,7 @@ asmlinkage unsigned int do_IRQ(struct pt stack_overflow_check(regs); #endif - if (likely(irq < NR_IRQS)) + if (likely(irq < nr_irqs)) generic_handle_irq(irq); else { if (!disable_apic) @@ -224,7 +224,7 @@ void fixup_irqs(cpumask_t map) unsigned int irq; static int warned; - for (irq = 0; irq < NR_IRQS; irq++) { + for (irq = 0; irq < nr_irqs; irq++) { cpumask_t mask; int break_affinity = 0; int set_affinity = 1; Index: linux-2.6/arch/x86/kernel/irqinit_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/irqinit_32.c +++ linux-2.6/arch/x86/kernel/irqinit_32.c @@ -91,7 +91,7 @@ void __init native_init_IRQ(void) */ for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) { int vector = FIRST_EXTERNAL_VECTOR + i; - if (i >= NR_IRQS) + if (i >= nr_irqs) break; /* SYSCALL_VECTOR was reserved in trap_init. */ if (!test_bit(vector, used_vectors)) Index: linux-2.6/arch/x86/kernel/irqinit_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/irqinit_64.c +++ linux-2.6/arch/x86/kernel/irqinit_64.c @@ -142,7 +142,7 @@ static void __init init_ISA_irqs (void) init_bsp_APIC(); init_8259A(0); - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; Index: linux-2.6/drivers/char/hpet.c =================================================================== --- linux-2.6.orig/drivers/char/hpet.c +++ linux-2.6/drivers/char/hpet.c @@ -222,7 +222,7 @@ static void hpet_timer_set_irq(struct hp 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; } Index: linux-2.6/drivers/char/random.c =================================================================== --- linux-2.6.orig/drivers/char/random.c +++ linux-2.6/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; /* Index: linux-2.6/drivers/char/vr41xx_giu.c =================================================================== --- linux-2.6.orig/drivers/char/vr41xx_giu.c +++ linux-2.6/drivers/char/vr41xx_giu.c @@ -641,7 +641,7 @@ static int __devinit giu_probe(struct pl } 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); Index: linux-2.6/drivers/net/3c59x.c =================================================================== --- linux-2.6.orig/drivers/net/3c59x.c +++ linux-2.6/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(struc 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); Index: linux-2.6/drivers/net/hamradio/baycom_ser_fdx.c =================================================================== --- linux-2.6.orig/drivers/net/hamradio/baycom_ser_fdx.c +++ linux-2.6/drivers/net/hamradio/baycom_ser_fdx.c @@ -416,10 +416,10 @@ static int ser12_open(struct net_device 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) { Index: linux-2.6/drivers/net/hamradio/scc.c =================================================================== --- linux-2.6.orig/drivers/net/hamradio/scc.c +++ linux-2.6/drivers/net/hamradio/scc.c @@ -1465,7 +1465,7 @@ static void z8530_init(void) printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2); flag=" "; - for (k = 0; k < NR_IRQS; k++) + for (k = 0; k < nr_irqs; k++) if (Ivec[k].used) { printk("%s%d", flag, k); @@ -1728,7 +1728,7 @@ static int scc_net_ioctl(struct net_devi if (hwcfg.irq == 2) hwcfg.irq = 9; - if (hwcfg.irq < 0 || hwcfg.irq >= NR_IRQS) + if (hwcfg.irq < 0 || hwcfg.irq >= nr_irqs) return -EINVAL; if (!Ivec[hwcfg.irq].used && hwcfg.irq) @@ -2148,7 +2148,7 @@ static void __exit scc_cleanup_driver(vo } /* To unload the port must be closed so no real IRQ pending */ - for (k=0; k < NR_IRQS ; k++) + for (k=0; k < nr_irqs ; k++) if (Ivec[k].used) free_irq(k, NULL); local_irq_enable(); Index: linux-2.6/drivers/net/wan/sbni.c =================================================================== --- linux-2.6.orig/drivers/net/wan/sbni.c +++ linux-2.6/drivers/net/wan/sbni.c @@ -318,7 +318,7 @@ sbni_pci_probe( struct net_device *dev continue; } - if( pci_irq_line <= 0 || pci_irq_line >= NR_IRQS ) + if( pci_irq_line <= 0 || pci_irq_line >= nr_irqs ) printk( KERN_WARNING " WARNING: The PCI BIOS assigned " "this PCI card to IRQ %d, which is unlikely " "to work!.\n" Index: linux-2.6/drivers/pci/intr_remapping.c =================================================================== --- linux-2.6.orig/drivers/pci/intr_remapping.c +++ linux-2.6/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 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 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_i 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 *ir 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) 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; } @@ -248,7 +248,7 @@ int free_irte(int irq) 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; } Index: linux-2.6/drivers/pcmcia/at91_cf.c =================================================================== --- linux-2.6.orig/drivers/pcmcia/at91_cf.c +++ linux-2.6/drivers/pcmcia/at91_cf.c @@ -273,7 +273,7 @@ static int __init at91_cf_probe(struct p 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) Index: linux-2.6/drivers/pcmcia/vrc4171_card.c =================================================================== --- linux-2.6.orig/drivers/pcmcia/vrc4171_card.c +++ linux-2.6/drivers/pcmcia/vrc4171_card.c @@ -639,7 +639,7 @@ static int __devinit vrc4171_card_setup( 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 != ',') Index: linux-2.6/drivers/rtc/rtc-vr41xx.c =================================================================== --- linux-2.6.orig/drivers/rtc/rtc-vr41xx.c +++ linux-2.6/drivers/rtc/rtc-vr41xx.c @@ -360,7 +360,7 @@ static int __devinit rtc_probe(struct pl 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 pl 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, Index: linux-2.6/drivers/scsi/aha152x.c =================================================================== --- linux-2.6.orig/drivers/scsi/aha152x.c +++ linux-2.6/drivers/scsi/aha152x.c @@ -337,7 +337,7 @@ CMD_INC_RESID(struct scsi_cmnd *cmd, int #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 Index: linux-2.6/drivers/serial/8250.c =================================================================== --- linux-2.6.orig/drivers/serial/8250.c +++ linux-2.6/drivers/serial/8250.c @@ -2433,7 +2433,7 @@ static void serial8250_config_port(struc 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) @@ -2964,7 +2964,7 @@ static int __init serial8250_init(void) "%d ports, IRQ sharing %sabled\n", nr_uarts, share_irqs ? "en" : "dis"); - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) spin_lock_init(&irq_lists[i].lock); ret = uart_register_driver(&serial8250_reg); Index: linux-2.6/drivers/serial/amba-pl010.c =================================================================== --- linux-2.6.orig/drivers/serial/amba-pl010.c +++ linux-2.6/drivers/serial/amba-pl010.c @@ -512,7 +512,7 @@ static int pl010_verify_port(struct uart 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; Index: linux-2.6/drivers/serial/amba-pl011.c =================================================================== --- linux-2.6.orig/drivers/serial/amba-pl011.c +++ linux-2.6/drivers/serial/amba-pl011.c @@ -572,7 +572,7 @@ static int pl010_verify_port(struct uart 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; Index: linux-2.6/drivers/serial/cpm_uart/cpm_uart_core.c =================================================================== --- linux-2.6.orig/drivers/serial/cpm_uart/cpm_uart_core.c +++ linux-2.6/drivers/serial/cpm_uart/cpm_uart_core.c @@ -589,7 +589,7 @@ static int cpm_uart_verify_port(struct u if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) 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; Index: linux-2.6/drivers/serial/m32r_sio.c =================================================================== --- linux-2.6.orig/drivers/serial/m32r_sio.c +++ linux-2.6/drivers/serial/m32r_sio.c @@ -922,7 +922,7 @@ static void m32r_sio_config_port(struct static int m32r_sio_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)) return -EINVAL; @@ -1162,7 +1162,7 @@ static int __init m32r_sio_init(void) printk(KERN_INFO "Serial: M32R SIO driver\n"); - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) spin_lock_init(&irq_lists[i].lock); ret = uart_register_driver(&m32r_sio_reg); Index: linux-2.6/drivers/serial/serial_core.c =================================================================== --- linux-2.6.orig/drivers/serial/serial_core.c +++ linux-2.6/drivers/serial/serial_core.c @@ -741,7 +741,7 @@ static int uart_set_info(struct uart_sta if (port->ops->verify_port) retval = port->ops->verify_port(port, &new_serial); - if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || + if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) || (new_serial.baud_base < 9600)) retval = -EINVAL; Index: linux-2.6/drivers/serial/serial_lh7a40x.c =================================================================== --- linux-2.6.orig/drivers/serial/serial_lh7a40x.c +++ linux-2.6/drivers/serial/serial_lh7a40x.c @@ -460,7 +460,7 @@ static int lh7a40xuart_verify_port (stru if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X) 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) /* *** FIXME: is this true? */ ret = -EINVAL; Index: linux-2.6/drivers/serial/sh-sci.c =================================================================== --- linux-2.6.orig/drivers/serial/sh-sci.c +++ linux-2.6/drivers/serial/sh-sci.c @@ -1157,7 +1157,7 @@ static int sci_verify_port(struct uart_p { struct sci_port *s = &sci_ports[port->line]; - if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > NR_IRQS) + if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs) return -EINVAL; if (ser->baud_base < 2400) /* No paper tape reader for Mitch.. */ Index: linux-2.6/drivers/serial/ucc_uart.c =================================================================== --- linux-2.6.orig/drivers/serial/ucc_uart.c +++ linux-2.6/drivers/serial/ucc_uart.c @@ -1066,7 +1066,7 @@ static int qe_uart_verify_port(struct ua if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) return -EINVAL; - if (ser->irq < 0 || ser->irq >= NR_IRQS) + if (ser->irq < 0 || ser->irq >= nr_irqs) return -EINVAL; if (ser->baud_base < 9600) Index: linux-2.6/drivers/xen/events.c =================================================================== --- linux-2.6.orig/drivers/xen/events.c +++ linux-2.6/drivers/xen/events.c @@ -150,7 +150,7 @@ static void init_evtchn_cpu_bindings(voi #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 @@ -234,12 +234,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; } @@ -772,7 +772,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++) @@ -804,7 +804,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()); 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 @@ -503,7 +503,7 @@ static int show_stat(struct seq_file *p, 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, 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, } 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 */ 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; } Index: linux-2.6/include/asm-x86/irq.h =================================================================== --- linux-2.6.orig/include/asm-x86/irq.h +++ linux-2.6/include/asm-x86/irq.h @@ -10,6 +10,9 @@ #include <asm/apicdef.h> #include <asm/irq_vectors.h> +extern int pin_map_size; +extern int first_free_entry; + static inline int irq_canonicalize(int irq) { return ((irq == 2) ? 9 : irq); Index: linux-2.6/include/linux/irq.h =================================================================== --- linux-2.6.orig/include/linux/irq.h +++ linux-2.6/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); Index: linux-2.6/kernel/irq/autoprobe.c =================================================================== --- linux-2.6.orig/kernel/irq/autoprobe.c +++ linux-2.6/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 lon int i; mask = 0; - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; unsigned int status; @@ -173,7 +173,7 @@ int probe_irq_off(unsigned long val) { int i, irq_found = 0, nr_irqs = 0; - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; unsigned int status; Index: linux-2.6/kernel/irq/chip.c =================================================================== --- linux-2.6.orig/kernel/irq/chip.c +++ linux-2.6/kernel/irq/chip.c @@ -27,7 +27,7 @@ void dynamic_irq_init(unsigned int irq) struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); return; } @@ -60,7 +60,7 @@ void dynamic_irq_cleanup(unsigned int ir struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); return; } @@ -92,7 +92,7 @@ int set_irq_chip(unsigned int irq, struc struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq); return -EINVAL; } @@ -121,7 +121,7 @@ int set_irq_type(unsigned int irq, unsig unsigned long flags; int ret = -ENXIO; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq); return -ENODEV; } @@ -148,7 +148,7 @@ int set_irq_data(unsigned int irq, void struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to install controller data for IRQ%d\n", irq); return -EINVAL; @@ -174,7 +174,7 @@ int set_irq_msi(unsigned int irq, struct struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to install msi data for IRQ%d\n", irq); return -EINVAL; @@ -200,7 +200,7 @@ int set_irq_chip_data(unsigned int irq, struct irq_desc *desc = irq_desc + irq; unsigned long flags; - if (irq >= NR_IRQS || !desc->chip) { + if (irq >= nr_irqs || !desc->chip) { printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq); return -EINVAL; } @@ -544,7 +544,7 @@ __set_irq_handler(unsigned int irq, irq_ struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to install type control for IRQ%d\n", irq); return; @@ -609,7 +609,7 @@ void __init set_irq_noprobe(unsigned int struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq); return; @@ -627,7 +627,7 @@ void __init set_irq_probe(unsigned int i struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq); return; 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, @@ -265,7 +266,7 @@ void early_init_irq_lock_class(void) { int i; - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) lockdep_set_class(&irq_desc[i].lock, &irq_desc_lock_class); } Index: linux-2.6/kernel/irq/manage.c =================================================================== --- linux-2.6.orig/kernel/irq/manage.c +++ linux-2.6/kernel/irq/manage.c @@ -34,7 +34,7 @@ void synchronize_irq(unsigned int irq) struct irq_desc *desc = irq_desc + irq; unsigned int status; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; do { @@ -143,7 +143,7 @@ void disable_irq_nosync(unsigned int irq struct irq_desc *desc = irq_desc + irq; unsigned long flags; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; spin_lock_irqsave(&desc->lock, flags); @@ -171,7 +171,7 @@ void disable_irq(unsigned int irq) { struct irq_desc *desc = irq_desc + irq; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; disable_irq_nosync(irq); @@ -214,7 +214,7 @@ void enable_irq(unsigned int irq) struct irq_desc *desc = irq_desc + irq; unsigned long flags; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; spin_lock_irqsave(&desc->lock, flags); @@ -290,7 +290,7 @@ int can_request_irq(unsigned int irq, un { struct irqaction *action; - if (irq >= NR_IRQS || irq_desc[irq].status & IRQ_NOREQUEST) + if (irq >= nr_irqs || irq_desc[irq].status & IRQ_NOREQUEST) return 0; action = irq_desc[irq].action; @@ -349,7 +349,7 @@ int setup_irq(unsigned int irq, struct i int shared = 0; int ret; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return -EINVAL; if (desc->chip == &no_irq_chip) @@ -503,7 +503,7 @@ void free_irq(unsigned int irq, void *de unsigned long flags; WARN_ON(in_interrupt()); - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return; desc = irq_desc + irq; @@ -617,7 +617,7 @@ int request_irq(unsigned int irq, irq_ha */ if ((irqflags & IRQF_SHARED) && !dev_id) return -EINVAL; - if (irq >= NR_IRQS) + if (irq >= nr_irqs) return -EINVAL; if (irq_desc[irq].status & IRQ_NOREQUEST) return -EINVAL; Index: linux-2.6/kernel/irq/proc.c =================================================================== --- linux-2.6.orig/kernel/irq/proc.c +++ linux-2.6/kernel/irq/proc.c @@ -234,7 +234,7 @@ void init_irq_proc(void) /* * Create entries for all existing IRQs. */ - for (i = 0; i < NR_IRQS; i++) + for (i = 0; i < nr_irqs; i++) register_irq_proc(i); } Index: linux-2.6/kernel/irq/resend.c =================================================================== --- linux-2.6.orig/kernel/irq/resend.c +++ linux-2.6/kernel/irq/resend.c @@ -33,8 +33,8 @@ static void resend_irqs(unsigned long ar struct irq_desc *desc; int irq; - while (!bitmap_empty(irqs_resend, NR_IRQS)) { - irq = find_first_bit(irqs_resend, NR_IRQS); + while (!bitmap_empty(irqs_resend, nr_irqs)) { + irq = find_first_bit(irqs_resend, nr_irqs); clear_bit(irq, irqs_resend); desc = irq_desc + irq; local_irq_disable(); Index: linux-2.6/kernel/irq/spurious.c =================================================================== --- linux-2.6.orig/kernel/irq/spurious.c +++ linux-2.6/kernel/irq/spurious.c @@ -91,7 +91,7 @@ static int misrouted_irq(int irq) int i; int ok = 0; - for (i = 1; i < NR_IRQS; i++) { + for (i = 1; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; if (i == irq) /* Already tried */ @@ -107,7 +107,7 @@ static int misrouted_irq(int irq) static void poll_spurious_irqs(unsigned long dummy) { int i; - for (i = 1; i < NR_IRQS; i++) { + for (i = 1; i < nr_irqs; i++) { struct irq_desc *desc = irq_desc + i; unsigned int status; ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 5/7] pci: make irq2_iommu to use dyn_array 2008-07-30 19:10 ` [PATCH 0/7] dyn_array support Yinghai Lu 2008-07-30 19:13 ` [PATCH 2/7] x86: introduce nr_irqs for 64bit v3 Yinghai Lu @ 2008-07-30 19:16 ` Yinghai Lu 2008-07-30 19:18 ` [PATCH 7/7] x86: make 64bit support dyn_array Yinghai Lu ` (6 subsequent siblings) 8 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-30 19:16 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton, jbarnes Cc: linux-kernel Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- drivers/pci/intr_remapping.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) Index: linux-2.6/drivers/pci/intr_remapping.c =================================================================== --- linux-2.6.orig/drivers/pci/intr_remapping.c +++ linux-2.6/drivers/pci/intr_remapping.c @@ -11,12 +11,14 @@ static struct ioapic_scope ir_ioapic[MAX static int ir_ioapic_num; int intr_remapping_enabled; -static struct { +static struct irq_2_iommu { struct intel_iommu *iommu; u16 irte_index; u16 sub_handle; u8 irte_mask; -} irq_2_iommu[NR_IRQS]; +} *irq_2_iommu; + +DEFINE_DYN_ARRAY(irq_2_iommu, sizeof(struct irq_2_iommu), nr_irqs, PAGE_SIZE, NULL); static DEFINE_SPINLOCK(irq_2_ir_lock); ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 7/7] x86: make 64bit support dyn_array 2008-07-30 19:10 ` [PATCH 0/7] dyn_array support Yinghai Lu 2008-07-30 19:13 ` [PATCH 2/7] x86: introduce nr_irqs for 64bit v3 Yinghai Lu 2008-07-30 19:16 ` [PATCH 5/7] pci: make irq2_iommu to use dyn_array Yinghai Lu @ 2008-07-30 19:18 ` Yinghai Lu 2008-07-30 19:27 ` [PATCH 1/7] x86: 64bit support more than 256 irq v1 Yinghai Lu ` (5 subsequent siblings) 8 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-30 19:18 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel set nr_irqs according to nr_cpu_ids, so could get small footprint when use big kernel. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/Kconfig | 2 ++ arch/x86/Kconfig | 1 + arch/x86/kernel/io_apic_64.c | 28 +++++++++++++++++++++------- arch/x86/kernel/setup.c | 6 ++++++ arch/x86/kernel/vmlinux_64.lds.S | 3 +++ 5 files changed, 33 insertions(+), 7 deletions(-) Index: linux-2.6/arch/Kconfig =================================================================== --- linux-2.6.orig/arch/Kconfig +++ linux-2.6/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 Index: linux-2.6/arch/x86/Kconfig =================================================================== --- linux-2.6.orig/arch/x86/Kconfig +++ linux-2.6/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 if X86_64 config ARCH_DEFCONFIG string Index: linux-2.6/arch/x86/kernel/io_apic_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/io_apic_64.c +++ linux-2.6/arch/x86/kernel/io_apic_64.c @@ -66,7 +66,7 @@ struct irq_cfg { }; /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ -static struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = { +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, }, @@ -85,6 +85,17 @@ static struct irq_cfg irq_cfg[NR_IRQS] _ [15] = { .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, }, }; +static struct irq_cfg *irq_cfg; + +static void __init init_work(void *data) +{ + struct dyn_array *da = data; + + memcpy(*da->name, irq_cfg_legacy, sizeof(irq_cfg_legacy)); +} + +DEFINE_DYN_ARRAY(irq_cfg, sizeof(struct irq_cfg), nr_irqs, PAGE_SIZE, init_work); + static int assign_irq_vector(int irq, cpumask_t mask); int first_system_vector = 0xfe; @@ -129,10 +140,9 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BU * 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) * @@ -141,8 +151,12 @@ int pin_map_size = PIN_MAP_SIZE; */ static struct irq_pin_list { - short apic, pin, next; -} irq_2_pin[PIN_MAP_SIZE]; + short apic, pin; + int next; +} *irq_2_pin; + +DEFINE_DYN_ARRAY(irq_2_pin, sizeof(struct irq_pin_list), pin_map_size, sizeof(struct irq_pin_list), NULL); + struct io_apic { unsigned int index; @@ -359,7 +373,7 @@ static void set_ioapic_affinity_irq(unsi * shared ISA-space IRQs, so we have to support them. We are super * fast in the common case, and fast for shared ISA-space IRQs. */ -int first_free_entry = NR_IRQS; +int first_free_entry; static void add_pin_to_irq(unsigned int irq, int apic, int pin) { struct irq_pin_list *entry = irq_2_pin + irq; Index: linux-2.6/arch/x86/kernel/setup.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup.c +++ linux-2.6/arch/x86/kernel/setup.c @@ -856,7 +856,13 @@ void __init setup_arch(char **cmdline_p) #endif prefill_possible_map(); + #ifdef CONFIG_X86_64 + /* need to wait for nr_cpu_ids settle down */ + if (nr_irqs == NR_IRQS) + nr_irqs = 32 * nr_cpu_ids + 224; + pin_map_size = nr_irqs * 2; + first_free_entry = nr_irqs; init_cpu_to_node(); #endif Index: linux-2.6/arch/x86/kernel/vmlinux_64.lds.S =================================================================== --- linux-2.6.orig/arch/x86/kernel/vmlinux_64.lds.S +++ linux-2.6/arch/x86/kernel/vmlinux_64.lds.S @@ -174,6 +174,9 @@ SECTIONS *(.x86cpuvendor.init) } __x86cpuvendor_end = .; + + DYN_ARRAY_INIT(8) + SECURITY_INIT . = ALIGN(8); ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 1/7] x86: 64bit support more than 256 irq v1 2008-07-30 19:10 ` [PATCH 0/7] dyn_array support Yinghai Lu ` (2 preceding siblings ...) 2008-07-30 19:18 ` [PATCH 7/7] x86: make 64bit support dyn_array Yinghai Lu @ 2008-07-30 19:27 ` Yinghai Lu 2008-07-30 19:37 ` [PATCH 3/7] add dyn_array support Yinghai Lu ` (4 subsequent siblings) 8 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-30 19:27 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel Dhaval Giani got: kernel BUG at arch/x86/kernel/io_apic_64.c:357! invalid opcode: 0000 [1] SMP CPU 24 ... his system (x3950) has 8 ioapic, irq > 256 caused by commit 9b7dc567d03d74a1fbae84e88949b6a60d922d82 Author: Thomas Gleixner <tglx@linutronix.de> Date: Fri May 2 20:10:09 2008 +0200 x86: unify interrupt vector defines The interrupt vector defines are copied 4 times around with minimal differences. Move them all into asm-x86/irq_vectors.h because 64bit allow same vector for different cpu to serve different irq need to create that array dynamically later Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Tested-by: Dhaval Giani <dhaval@linux.vnet.ibm.com> --- include/asm-x86/irq_vectors.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) Index: linux-2.6/include/asm-x86/irq_vectors.h =================================================================== --- linux-2.6.orig/include/asm-x86/irq_vectors.h +++ linux-2.6/include/asm-x86/irq_vectors.h @@ -113,28 +113,26 @@ # if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_PARAVIRT) || defined(CONFIG_X86_VISWS) +#ifdef CONFIG_X86_64 +# define NR_IRQS (32 * NR_CPUS + 224) +#else # define NR_IRQS 224 - -# if (224 >= 32 * NR_CPUS) -# define NR_IRQ_VECTORS NR_IRQS -# else -# define NR_IRQ_VECTORS (32 * NR_CPUS) -# endif +#endif # else /* IO_APIC || PARAVIRT */ # define NR_IRQS 16 -# define NR_IRQ_VECTORS NR_IRQS # endif #else /* !VISWS && !VOYAGER */ # define NR_IRQS 224 -# define NR_IRQ_VECTORS NR_IRQS #endif /* VISWS */ +#define NR_IRQ_VECTORS NR_IRQS + /* Voyager specific defines */ /* These define the CPIs we use in linux */ #define VIC_CPI_LEVEL0 0 ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 3/7] add dyn_array support 2008-07-30 19:10 ` [PATCH 0/7] dyn_array support Yinghai Lu ` (3 preceding siblings ...) 2008-07-30 19:27 ` [PATCH 1/7] x86: 64bit support more than 256 irq v1 Yinghai Lu @ 2008-07-30 19:37 ` Yinghai Lu 2008-07-30 19:40 ` [PATCH 6/7] irq: make irq_desc to use dyn_array Yinghai Lu ` (3 subsequent siblings) 8 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-30 19:37 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel [ so could put some crazy big array in bootmem in init stage. use CONFIG_HAVE_DYN_ARRAY to enable it or not Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- include/asm-generic/vmlinux.lds.h | 7 +++++++ include/linux/init.h | 23 +++++++++++++++++++++++ init/main.c | 25 +++++++++++++++++++++++++ 3 files changed, 55 insertions(+) Index: linux-2.6/include/asm-generic/vmlinux.lds.h =================================================================== --- linux-2.6.orig/include/asm-generic/vmlinux.lds.h +++ linux-2.6/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 \ .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__security_initcall_start) = .; \ Index: linux-2.6/include/linux/init.h =================================================================== --- linux-2.6.orig/include/linux/init.h +++ linux-2.6/include/linux/init.h @@ -249,6 +249,29 @@ struct obs_kernel_param { /* Relies on boot_command_line being set */ void __init parse_early_param(void); + +struct dyn_array { + void **name; + unsigned long size; + unsigned int *nr; + unsigned long align; + void (*init_work)(void *); +}; +extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[]; + +#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ + static struct dyn_array __dyn_array_##nameX __initdata = \ + { .name = (void **)&nameX,\ + .size = sizeX,\ + .nr = &nrX,\ + .align = alignX,\ + .init_work = init_workX,\ + }; \ + static struct dyn_array *__dyn_array_ptr_##nameX __used \ + __attribute__((__section__(".dyn_array.init"))) = \ + &__dyn_array_##nameX + +extern void pre_alloc_dyn_array(void); #endif /* __ASSEMBLY__ */ /** Index: linux-2.6/init/main.c =================================================================== --- linux-2.6.orig/init/main.c +++ linux-2.6/init/main.c @@ -539,6 +539,29 @@ void __init __weak thread_info_cache_ini { } +void pre_alloc_dyn_array(void) +{ +#ifdef CONFIG_HAVE_DYN_ARRAY + unsigned long size, phys = 0; + struct dyn_array **daa; + + for (daa = __dyn_array_start ; daa < __dyn_array_end; daa++) { + struct dyn_array *da = *daa; + + size = da->size * (*da->nr); + print_fn_descriptor_symbol("dyna_array %s ", da->name); + printk(KERN_CONT "size:%#lx nr:%d align:%#lx", + da->size, *da->nr, da->align); + *da->name = __alloc_bootmem_nopanic(size, da->align, phys); + phys = virt_to_phys(*da->name); + printk(KERN_CONT " ==> [%#lx - %#lx]\n", phys, phys + size); + + if (da->init_work) + da->init_work(da); + } +#endif +} + asmlinkage void __init start_kernel(void) { char * command_line; @@ -576,6 +599,8 @@ asmlinkage void __init start_kernel(void printk(KERN_NOTICE); printk(linux_banner); setup_arch(&command_line); + printk(KERN_INFO "nr_irqs: %d\n", nr_irqs); + pre_alloc_dyn_array(); mm_init_owner(&init_mm, &init_task); setup_command_line(command_line); unwind_setup(); ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 6/7] irq: make irq_desc to use dyn_array 2008-07-30 19:10 ` [PATCH 0/7] dyn_array support Yinghai Lu ` (4 preceding siblings ...) 2008-07-30 19:37 ` [PATCH 3/7] add dyn_array support Yinghai Lu @ 2008-07-30 19:40 ` Yinghai Lu 2008-07-30 19:40 ` [PATCH 4/7] random: make irq_timer_state " Yinghai Lu ` (2 subsequent siblings) 8 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-30 19:40 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- include/linux/irq.h | 4 ++++ kernel/irq/handle.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) Index: linux-2.6/include/linux/irq.h =================================================================== --- linux-2.6.orig/include/linux/irq.h +++ linux-2.6/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: Index: linux-2.6/kernel/irq/handle.c =================================================================== --- linux-2.6.orig/kernel/irq/handle.c +++ linux-2.6/kernel/irq/handle.c @@ -48,6 +48,36 @@ handle_bad_irq(unsigned int irq, struct * Controller mappings for all interrupt sources: */ int nr_irqs = NR_IRQS; + +#ifdef CONFIG_HAVE_DYN_ARRAY +static struct irq_desc irq_desc_init = { + .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; + 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] __cach #endif } }; +#endif /* * What should we do if we get a hw irq event on an illegal vector? ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 4/7] random: make irq_timer_state to use dyn_array 2008-07-30 19:10 ` [PATCH 0/7] dyn_array support Yinghai Lu ` (5 preceding siblings ...) 2008-07-30 19:40 ` [PATCH 6/7] irq: make irq_desc to use dyn_array Yinghai Lu @ 2008-07-30 19:40 ` Yinghai Lu 2008-07-31 4:09 ` [PATCH 0/3] dyn_array support #2 Yinghai Lu 2008-08-01 20:13 ` [PATCH 0/7] dyn_array support Eric W. Biederman 8 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-30 19:40 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- drivers/char/random.c | 6 ++++++ 1 file changed, 6 insertions(+) Index: linux-2.6/drivers/char/random.c =================================================================== --- linux-2.6.orig/drivers/char/random.c +++ linux-2.6/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 ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 0/3] dyn_array support #2 2008-07-30 19:10 ` [PATCH 0/7] dyn_array support Yinghai Lu ` (6 preceding siblings ...) 2008-07-30 19:40 ` [PATCH 4/7] random: make irq_timer_state " Yinghai Lu @ 2008-07-31 4:09 ` Yinghai Lu 2008-07-31 4:10 ` [PATCH 1/3] serial: change irq_lists to use dyn_array Yinghai Lu ` (5 more replies) 2008-08-01 20:13 ` [PATCH 0/7] dyn_array support Eric W. Biederman 8 siblings, 6 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-31 4:09 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel please check the patches adding dyn_array and nr_irqs #2 Thanks YH ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 1/3] serial: change irq_lists to use dyn_array 2008-07-31 4:09 ` [PATCH 0/3] dyn_array support #2 Yinghai Lu @ 2008-07-31 4:10 ` Yinghai Lu 2008-07-31 5:58 ` Eric W. Biederman 2008-07-31 8:26 ` [PATCH] serial: change remove NR_IRQS in 8250.c Yinghai Lu 2008-07-31 4:11 ` [PATCH 2/3] add per_cpu_dyn_array support Yinghai Lu ` (4 subsequent siblings) 5 siblings, 2 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-31 4:10 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- drivers/serial/8250.c | 5 +++++ 1 file changed, 5 insertions(+) Index: linux-2.6/drivers/serial/8250.c =================================================================== --- linux-2.6.orig/drivers/serial/8250.c +++ linux-2.6/drivers/serial/8250.c @@ -149,7 +149,12 @@ struct irq_info { struct list_head *head; }; +#if defined(CONFIG_HAVE_DYN_ARRAY) && !defined(MODULE) +static struct irq_info *irq_lists; +DEFINE_DYN_ARRAY(irq_lists, sizeof(struct irq_info), nr_irqs, PAGE_SIZE, NULL); +#else static struct irq_info irq_lists[NR_IRQS]; +#endif /* * Here we define the default xmit fifo size used for each type of UART. ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 1/3] serial: change irq_lists to use dyn_array 2008-07-31 4:10 ` [PATCH 1/3] serial: change irq_lists to use dyn_array Yinghai Lu @ 2008-07-31 5:58 ` Eric W. Biederman 2008-07-31 8:26 ` [PATCH] serial: change remove NR_IRQS in 8250.c Yinghai Lu 1 sibling, 0 replies; 44+ messages in thread From: Eric W. Biederman @ 2008-07-31 5:58 UTC (permalink / raw) To: Yinghai Lu Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel Yinghai Lu <yhlu.kernel@gmail.com> writes: > Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Instead of fixing this to work like every other driver you are introducing a dynarray? This seriously looks like an example of papering over a problem instead of fixing it correctly. Eric ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH] serial: change remove NR_IRQS in 8250.c 2008-07-31 4:10 ` [PATCH 1/3] serial: change irq_lists to use dyn_array Yinghai Lu 2008-07-31 5:58 ` Eric W. Biederman @ 2008-07-31 8:26 ` Yinghai Lu 2008-07-31 11:50 ` Eric W. Biederman 1 sibling, 1 reply; 44+ messages in thread From: Yinghai Lu @ 2008-07-31 8:26 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel replace [PATCH] serial: change irq_lists to use dyn_array use small array with index to handle irq locking for serial port hope 32 slot is enough Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- drivers/serial/8250.c | 73 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 6 deletions(-) Index: linux-2.6/drivers/serial/8250.c =================================================================== --- linux-2.6.orig/drivers/serial/8250.c +++ linux-2.6/drivers/serial/8250.c @@ -149,7 +149,55 @@ struct irq_info { struct list_head *head; }; -static struct irq_info irq_lists[NR_IRQS]; +struct irq_info_pair { + struct irq_info irq_info; + int irq_no; +}; + +#define NR_IRQ_INFO_PAIR 32 + +static struct irq_info_pair irq_pair_lists[NR_IRQ_INFO_PAIR] = { + [0 ... NR_IRQ_INFO_PAIR-1] = { + .irq_no = -1, + } +}; + +static struct irq_info *get_irq_info(int irq, int with_free) +{ + int i, first_free = -1; + + for (i = 0; i < NR_IRQ_INFO_PAIR; i++) { + if (irq_pair_lists[i].irq_no == irq) + return &irq_pair_lists[i].irq_info; + if (irq_pair_lists[i].irq_no == -1 && first_free == -1) + first_free = i; + } + if (!with_free) + return NULL; + + if (first_free != -1) { + irq_pair_lists[first_free].irq_no = irq; + return &irq_pair_lists[first_free].irq_info; + } + + WARN_ON("NR_IRQ_INFO_PAIR too small"); + + return NULL; +} + +static void check_free_irq_info(int irq_no) +{ + + int i; + + for (i = 0; i < NR_IRQ_INFO_PAIR; i++) { + if (irq_pair_lists[i].irq_no != irq_no) + continue; + + irq_pair_lists[i].irq_no = -1; + break; + } +} /* * Here we define the default xmit fifo size used for each type of UART. @@ -1554,9 +1602,12 @@ static void serial_do_unlink(struct irq_ static int serial_link_irq_chain(struct uart_8250_port *up) { - struct irq_info *i = irq_lists + up->port.irq; + struct irq_info *i = get_irq_info(up->port.irq, 1); int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; + if (!i) + return -1; + spin_lock_irq(&i->lock); if (i->head) { @@ -1580,14 +1631,24 @@ static int serial_link_irq_chain(struct static void serial_unlink_irq_chain(struct uart_8250_port *up) { - struct irq_info *i = irq_lists + up->port.irq; + int irq_no = up->port.irq; + struct irq_info *i = get_irq_info(irq_no, 0); + int empty = 0; + + if (!i) + return; BUG_ON(i->head == NULL); - if (list_empty(i->head)) + if (list_empty(i->head)) { free_irq(up->port.irq, i); + empty = 1; + } serial_do_unlink(i, up); + + if (empty) + check_free_irq_info(irq_no); } /* Base timer interval for polling */ @@ -2964,8 +3025,8 @@ static int __init serial8250_init(void) "%d ports, IRQ sharing %sabled\n", nr_uarts, share_irqs ? "en" : "dis"); - for (i = 0; i < nr_irqs; i++) - spin_lock_init(&irq_lists[i].lock); + for (i = 0; i < NR_IRQ_INFO_PAIR; i++) + spin_lock_init(&irq_pair_lists[i].irq_info.lock); ret = uart_register_driver(&serial8250_reg); if (ret) ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] serial: change remove NR_IRQS in 8250.c 2008-07-31 8:26 ` [PATCH] serial: change remove NR_IRQS in 8250.c Yinghai Lu @ 2008-07-31 11:50 ` Eric W. Biederman 2008-07-31 13:57 ` Alan Cox 2008-08-01 3:20 ` Yinghai Lu 0 siblings, 2 replies; 44+ messages in thread From: Eric W. Biederman @ 2008-07-31 11:50 UTC (permalink / raw) To: Yinghai Lu Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel > replace > [PATCH] serial: change irq_lists to use dyn_array > use small array with index to handle irq locking for serial port > hope 32 slot is enough Could you size this array by NR_UARTS (our worst case usage) and place irq_no in struct irq_info? Also you want to hold irq_info->lock when you set or clear irq_no. Just to be on the safe side. I expect we can avoid clearing the irq_no in the irq_lists and prevent a few more races from being a possibility. Eric ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] serial: change remove NR_IRQS in 8250.c 2008-07-31 11:50 ` Eric W. Biederman @ 2008-07-31 13:57 ` Alan Cox 2008-07-31 18:10 ` Eric W. Biederman 2008-08-01 3:20 ` Yinghai Lu 1 sibling, 1 reply; 44+ messages in thread From: Alan Cox @ 2008-07-31 13:57 UTC (permalink / raw) To: Eric W. Biederman Cc: Yinghai Lu, Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel On Thu, 31 Jul 2008 04:50:21 -0700 ebiederm@xmission.com (Eric W. Biederman) wrote: > > replace > > [PATCH] serial: change irq_lists to use dyn_array > > use small array with index to handle irq locking for serial port > > hope 32 slot is enough > > Could you size this array by NR_UARTS (our worst case usage) > and place irq_no in struct irq_info? NR_UARTS is likely to go away in time so don't get attached to it ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] serial: change remove NR_IRQS in 8250.c 2008-07-31 13:57 ` Alan Cox @ 2008-07-31 18:10 ` Eric W. Biederman 2008-07-31 23:15 ` Alan Cox 0 siblings, 1 reply; 44+ messages in thread From: Eric W. Biederman @ 2008-07-31 18:10 UTC (permalink / raw) To: Alan Cox Cc: Yinghai Lu, Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel Alan Cox <alan@lxorguk.ukuu.org.uk> writes: > On Thu, 31 Jul 2008 04:50:21 -0700 > ebiederm@xmission.com (Eric W. Biederman) wrote: > >> > replace >> > [PATCH] serial: change irq_lists to use dyn_array >> > use small array with index to handle irq locking for serial port >> > hope 32 slot is enough >> >> Could you size this array by NR_UARTS (our worst case usage) >> and place irq_no in struct irq_info? > > NR_UARTS is likely to go away in time so don't get attached to it I'm not attached to it, but NR_UARTS is a closer approximation to what we are trying to do then YH's hard coded 32. Do you know if we actually need the list of uarts per irq or if request_irq having a shared isa would work? The practical question is how do we cleanly kill the array irq_lists[NR_IRQS]. YH's hack where he isn't paying attention to what the code is doing and just trying to avoid the problem is not something I am fond of seeing being merged. It is also true that sorting out 8250.c and by extension the other serial drivers that have cloned it is the significant non-arch piece of work needed to kill NR_IRQs Eric ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] serial: change remove NR_IRQS in 8250.c 2008-07-31 18:10 ` Eric W. Biederman @ 2008-07-31 23:15 ` Alan Cox 0 siblings, 0 replies; 44+ messages in thread From: Alan Cox @ 2008-07-31 23:15 UTC (permalink / raw) To: Eric W. Biederman Cc: Yinghai Lu, Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel > The practical question is how do we cleanly kill the array > irq_lists[NR_IRQS]. YH's hack where he isn't paying attention to what > the code is doing and just trying to avoid the problem is not > something I am fond of seeing being merged. > > It is also true that sorting out 8250.c and by extension the other > serial drivers that have cloned it is the significant non-arch > piece of work needed to kill NR_IRQs Lets just make it happen next week. It needs doing and while it wasn't top of the serial work list this is a good reason to kill it off. Alan ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] serial: change remove NR_IRQS in 8250.c 2008-07-31 11:50 ` Eric W. Biederman 2008-07-31 13:57 ` Alan Cox @ 2008-08-01 3:20 ` Yinghai Lu 1 sibling, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-08-01 3:20 UTC (permalink / raw) To: Eric W. Biederman Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel On Thu, Jul 31, 2008 at 4:50 AM, Eric W. Biederman <ebiederm@xmission.com> wrote: >> replace >> [PATCH] serial: change irq_lists to use dyn_array >> use small array with index to handle irq locking for serial port >> hope 32 slot is enough > > Could you size this array by NR_UARTS (our worst case usage) how about crazy user set that too big? > and place irq_no in struct irq_info? should be ok > > Also you want to hold irq_info->lock when you set or clear irq_no. > Just to be on the safe side. I expect we can avoid clearing the irq_no > in the irq_lists and prevent a few more races from being a possibility. will try YH ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 2/3] add per_cpu_dyn_array support 2008-07-31 4:09 ` [PATCH 0/3] dyn_array support #2 Yinghai Lu 2008-07-31 4:10 ` [PATCH 1/3] serial: change irq_lists to use dyn_array Yinghai Lu @ 2008-07-31 4:11 ` Yinghai Lu 2008-07-31 4:12 ` [PATCH 3/3] irq: make irqs in kernel stat use per_cpu_dyn_array Yinghai Lu ` (3 subsequent siblings) 5 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-31 4:11 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel so could make array in per_cpu is allocated dynamically too 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 | 57 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 5 deletions(-) Index: linux-2.6/arch/x86/kernel/setup_percpu.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_percpu.c +++ linux-2.6/arch/x86/kernel/setup_percpu.c @@ -140,7 +140,7 @@ static void __init setup_cpu_pda_map(voi */ 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", Index: linux-2.6/include/asm-generic/vmlinux.lds.h =================================================================== --- linux-2.6.orig/include/asm-generic/vmlinux.lds.h +++ linux-2.6/include/asm-generic/vmlinux.lds.h @@ -220,6 +220,12 @@ VMLINUX_SYMBOL(__dyn_array_start) = .; \ *(.dyn_array.init) \ VMLINUX_SYMBOL(__dyn_array_end) = .; \ + } \ + . = ALIGN((align)); \ + .per_cpu_dyn_array.init : AT(ADDR(.per_cpu_dyn_array.init) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__per_cpu_dyn_array_start) = .; \ + *(.per_cpu_dyn_array.init) \ + VMLINUX_SYMBOL(__per_cpu_dyn_array_end) = .; \ } #define SECURITY_INIT \ .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \ Index: linux-2.6/include/linux/init.h =================================================================== --- linux-2.6.orig/include/linux/init.h +++ linux-2.6/include/linux/init.h @@ -258,12 +258,13 @@ struct dyn_array { void (*init_work)(void *); }; extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[]; +extern struct dyn_array *__per_cpu_dyn_array_start[], *__per_cpu_dyn_array_end[]; -#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ +#define DEFINE_DYN_ARRAY_ADDR(nameX, addrX, sizeX, nrX, alignX, init_workX) \ static struct dyn_array __dyn_array_##nameX __initdata = \ - { .name = (void **)&nameX,\ + { .name = (void **)&(nameX),\ .size = sizeX,\ - .nr = &nrX,\ + .nr = &(nrX),\ .align = alignX,\ .init_work = init_workX,\ }; \ @@ -271,7 +272,27 @@ extern struct dyn_array *__dyn_array_sta __attribute__((__section__(".dyn_array.init"))) = \ &__dyn_array_##nameX +#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ + DEFINE_DYN_ARRAY_ADDR(nameX, nameX, sizeX, nrX, alignX, init_workX) + +#define DEFINE_PER_CPU_DYN_ARRAY_ADDR(nameX, addrX, sizeX, nrX, alignX, init_workX) \ + static struct dyn_array __per_cpu_dyn_array_##nameX __initdata = \ + { .name = (void **)&(addrX),\ + .size = sizeX,\ + .nr = &(nrX),\ + .align = alignX,\ + .init_work = init_workX,\ + }; \ + static struct dyn_array *__per_cpu_dyn_array_ptr_##nameX __used \ + __attribute__((__section__(".per_cpu_dyn_array.init"))) = \ + &__per_cpu_dyn_array_##nameX + +#define DEFINE_PER_CPU_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ + DEFINE_PER_CPU_DYN_ARRAY_ADDR(nameX, nameX, nrX, alignX, init_workX) + extern void pre_alloc_dyn_array(void); +extern unsigned long per_cpu_dyn_array_size(void); +extern void per_cpu_alloc_dyn_array(int cpu, char *ptr); #endif /* __ASSEMBLY__ */ /** Index: linux-2.6/init/main.c =================================================================== --- linux-2.6.orig/init/main.c +++ linux-2.6/init/main.c @@ -562,6 +562,63 @@ void pre_alloc_dyn_array(void) #endif } +unsigned long per_cpu_dyn_array_size(void) +{ + unsigned long total_size = 0; +#ifdef CONFIG_HAVE_DYN_ARRAY + unsigned long size; + struct dyn_array **daa; + + for (daa = __per_cpu_dyn_array_start ; daa < __per_cpu_dyn_array_end; daa++) { + struct dyn_array *da = *daa; + + size = da->size * (*da->nr); + print_fn_descriptor_symbol("per_cpu_dyna_array %s ", da->name); + printk(KERN_CONT "size:%#lx nr:%d align:%#lx\n", + da->size, *da->nr, da->align); + total_size += roundup(size, da->align); + } + if (total_size) + printk(KERN_DEBUG "per_cpu_dyna_array total_size: %#lx\n", + total_size); +#endif + return total_size; +} + +void per_cpu_alloc_dyn_array(int cpu, char *ptr) +{ +#ifdef CONFIG_HAVE_DYN_ARRAY + unsigned long size, phys; + struct dyn_array **daa; + unsigned long addr; + void **array; + + phys = virt_to_phys(ptr); + + for (daa = __per_cpu_dyn_array_start ; daa < __per_cpu_dyn_array_end; daa++) { + struct dyn_array *da = *daa; + + size = da->size * (*da->nr); + print_fn_descriptor_symbol("per_cpu_dyna_array %s ", da->name); + printk(KERN_CONT "size:%#lx nr:%d align:%#lx", + da->size, *da->nr, da->align); + + phys = roundup(phys, da->align); + addr = (unsigned long)da->name; + addr += per_cpu_offset(cpu); + array = (void **)addr; + *array = phys_to_virt(phys); + *da->name = *array; /* so init_work could use it directly */ + printk(KERN_CONT " %p ==> [%#lx - %#lx]\n", array, phys, phys + size); + phys += size; + + if (da->init_work) { + da->init_work(da); + } + } +#endif +} + asmlinkage void __init start_kernel(void) { char * command_line; ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 3/3] irq: make irqs in kernel stat use per_cpu_dyn_array 2008-07-31 4:09 ` [PATCH 0/3] dyn_array support #2 Yinghai Lu 2008-07-31 4:10 ` [PATCH 1/3] serial: change irq_lists to use dyn_array Yinghai Lu 2008-07-31 4:11 ` [PATCH 2/3] add per_cpu_dyn_array support Yinghai Lu @ 2008-07-31 4:12 ` Yinghai Lu 2008-07-31 10:14 ` [PATCH] x86 remove irq_vectors_limit.h Yinghai Lu ` (2 subsequent siblings) 5 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-31 4:12 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel 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 deletion(-) Index: linux-2.6/include/linux/kernel_stat.h =================================================================== --- linux-2.6.orig/include/linux/kernel_stat.h +++ linux-2.6/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); Index: linux-2.6/kernel/sched.c =================================================================== --- linux-2.6.orig/kernel/sched.c +++ linux-2.6/kernel/sched.c @@ -4022,9 +4022,12 @@ static inline void idle_balance(int cpu, #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. ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH] x86 remove irq_vectors_limit.h 2008-07-31 4:09 ` [PATCH 0/3] dyn_array support #2 Yinghai Lu ` (2 preceding siblings ...) 2008-07-31 4:12 ` [PATCH 3/3] irq: make irqs in kernel stat use per_cpu_dyn_array Yinghai Lu @ 2008-07-31 10:14 ` Yinghai Lu 2008-07-31 16:32 ` [PATCH 0/3] dyn_array support #2 Mike Travis 2008-07-31 21:51 ` Peter Zijlstra 5 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-31 10:14 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel no user later 1. need to make 32bit to support dyn_array for irq_vector[] 2. also need to probe nr_irqs via madt and mptable Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Index: linux-2.6/include/asm-x86/mach-generic/irq_vectors_limits.h =================================================================== --- linux-2.6.orig/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 */ Index: linux-2.6/include/asm-x86/summit/irq_vectors_limits.h =================================================================== --- linux-2.6.orig/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 */ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 0/3] dyn_array support #2 2008-07-31 4:09 ` [PATCH 0/3] dyn_array support #2 Yinghai Lu ` (3 preceding siblings ...) 2008-07-31 10:14 ` [PATCH] x86 remove irq_vectors_limit.h Yinghai Lu @ 2008-07-31 16:32 ` Mike Travis 2008-07-31 18:21 ` Yinghai Lu 2008-07-31 21:51 ` Peter Zijlstra 5 siblings, 1 reply; 44+ messages in thread From: Mike Travis @ 2008-07-31 16:32 UTC (permalink / raw) To: Yinghai Lu Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Andrew Morton, linux-kernel, Jack Steiner Yinghai Lu wrote: > please check the patches adding dyn_array and nr_irqs #2 > > Thanks > > YH It appears that the primary difference between your patch and Eric's is that you estimate the number of IRQ's required based on the number of cpus present, while Eric's patch grows the list based on the IRQ's being requested. For soon to be "power" desktop systems (say dual 8 core Nahalem's w/HT), you're reserving IRQ's for 32 cpus on a system which probably has one I/O bus (or maybe two). A dual socket Larabbee system will have 256 cpus. An SGI UV system has more of a "building block" approach, where you can grow all three (cpus, memory, I/O) independently. One other very nice feature of Eric's approach is that the new "IRQ" struct being requested can be created in "node local" memory, cutting down significantly the number of "cross node" accesses. Plus, I still like Ingo's suggestion to not change NR_IRQS ==> nr_irqs. CONFIG_ARCH_HAS_DYNAMIC_IRQS spells out exactly what NR_IRQS means. (Even more accurate would be CONFIG_ARCH_HAS_DYNAMIC_NR_IRQS.) The DEFINE_DYN_ARRAY could be the following. (Changing general purpose DYN_ARRAY to specifically purposed IRQ_ARRAY.) #ifdef CONFIG_ARCH_HAS_DYNAMIC_IRQS #define DEFINE_IRQ_ARRAY <new variable irq array [or list] definition> #else #define DEFINE_IRQ_ARRAY <old static irq array> #endif For the immediate problem, unraveling the code merge back to IRQ's based on NR_IOAPICS would seem to be the least intrusive. Thanks, Mike ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 0/3] dyn_array support #2 2008-07-31 16:32 ` [PATCH 0/3] dyn_array support #2 Mike Travis @ 2008-07-31 18:21 ` Yinghai Lu 0 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-07-31 18:21 UTC (permalink / raw) To: Mike Travis Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Andrew Morton, linux-kernel, Jack Steiner On Thu, Jul 31, 2008 at 9:32 AM, Mike Travis <travis@sgi.com> wrote: > Yinghai Lu wrote: >> please check the patches adding dyn_array and nr_irqs #2 >> >> Thanks >> >> YH > > > It appears that the primary difference between your patch and Eric's > is that you estimate the number of IRQ's required based on the number > of cpus present, while Eric's patch grows the list based on the IRQ's > being requested. For soon to be "power" desktop systems (say dual 8 core > Nahalem's w/HT), you're reserving IRQ's for 32 cpus on a system which > probably has one I/O bus (or maybe two). A dual socket Larabbee system > will have 256 cpus. An SGI UV system has more of a "building block" > approach, where you can grow all three (cpus, memory, I/O) independently. > > One other very nice feature of Eric's approach is that the new "IRQ" > struct being requested can be created in "node local" memory, cutting > down significantly the number of "cross node" accesses. where is Eric's patch? I didn't get it... > > Plus, I still like Ingo's suggestion to not change NR_IRQS ==> nr_irqs. > CONFIG_ARCH_HAS_DYNAMIC_IRQS spells out exactly what NR_IRQS means. > (Even more accurate would be CONFIG_ARCH_HAS_DYNAMIC_NR_IRQS.) not every array need to be changed to dyn_array, if the static array is not big enough. and some DEFINE_BIT map is using NR_IRQS. > > The DEFINE_DYN_ARRAY could be the following. (Changing general purpose > DYN_ARRAY to specifically purposed IRQ_ARRAY.) dyn_array is some more generic, and nr_irqs is one of it's user > > #ifdef CONFIG_ARCH_HAS_DYNAMIC_IRQS > #define DEFINE_IRQ_ARRAY <new variable irq array [or list] definition> > #else > #define DEFINE_IRQ_ARRAY <old static irq array> > #endif > > For the immediate problem, unraveling the code merge back to IRQ's based > on NR_IOAPICS would seem to be the least intrusive. less intrusive way could be use dyn_array and make nr_irqs to be set via acpi_madt_oem_check... YH ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 0/3] dyn_array support #2 2008-07-31 4:09 ` [PATCH 0/3] dyn_array support #2 Yinghai Lu ` (4 preceding siblings ...) 2008-07-31 16:32 ` [PATCH 0/3] dyn_array support #2 Mike Travis @ 2008-07-31 21:51 ` Peter Zijlstra 2008-07-31 22:07 ` Yinghai Lu 2008-07-31 22:14 ` Eric W. Biederman 5 siblings, 2 replies; 44+ messages in thread From: Peter Zijlstra @ 2008-07-31 21:51 UTC (permalink / raw) To: Yinghai Lu Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel, benh On Wed, 2008-07-30 at 21:09 -0700, Yinghai Lu wrote: > please check the patches adding dyn_array and nr_irqs #2 Why can't we use a radix tree like powerpc does? ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 0/3] dyn_array support #2 2008-07-31 21:51 ` Peter Zijlstra @ 2008-07-31 22:07 ` Yinghai Lu 2008-07-31 22:25 ` Yinghai Lu 2008-07-31 22:14 ` Eric W. Biederman 1 sibling, 1 reply; 44+ messages in thread From: Yinghai Lu @ 2008-07-31 22:07 UTC (permalink / raw) To: Peter Zijlstra Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel, benh On Thu, Jul 31, 2008 at 2:51 PM, Peter Zijlstra <peterz@infradead.org> wrote: > On Wed, 2008-07-30 at 21:09 -0700, Yinghai Lu wrote: >> please check the patches adding dyn_array and nr_irqs #2 > > Why can't we use a radix tree like powerpc does? > which file in arch/power i could look? YH ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 0/3] dyn_array support #2 2008-07-31 22:07 ` Yinghai Lu @ 2008-07-31 22:25 ` Yinghai Lu 2008-08-01 3:52 ` Yinghai Lu 0 siblings, 1 reply; 44+ messages in thread From: Yinghai Lu @ 2008-07-31 22:25 UTC (permalink / raw) To: Dhaval Giani, Mike Travis Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Andrew Morton, linux-kernel, benh, Peter Zijlstra [-- Attachment #1: Type: text/plain, Size: 145 bytes --] please try attach nr_irqs dyn_array quilt patchset on your x3960 and UV... it autodetect nr_irqs need apply to tip/master. Thanks Yinghai Lu [-- Attachment #2: dyn_array_nr_irqs_patches.tar.bz2 --] [-- Type: application/x-bzip2, Size: 17249 bytes --] ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 0/3] dyn_array support #2 2008-07-31 22:25 ` Yinghai Lu @ 2008-08-01 3:52 ` Yinghai Lu 0 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-08-01 3:52 UTC (permalink / raw) To: Dhaval Giani, Mike Travis Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Andrew Morton, linux-kernel, benh, Peter Zijlstra [-- Attachment #1: Type: text/plain, Size: 99 bytes --] please check v2 , base to tip/master 1. address eric about irq_info changing 2. less print out YH [-- Attachment #2: dyn_array_nr_irqs_patches_v2.tar.bz2 --] [-- Type: application/x-bzip2, Size: 17843 bytes --] ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 0/3] dyn_array support #2 2008-07-31 21:51 ` Peter Zijlstra 2008-07-31 22:07 ` Yinghai Lu @ 2008-07-31 22:14 ` Eric W. Biederman 1 sibling, 0 replies; 44+ messages in thread From: Eric W. Biederman @ 2008-07-31 22:14 UTC (permalink / raw) To: Peter Zijlstra Cc: Yinghai Lu, Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel, benh Peter Zijlstra <peterz@infradead.org> writes: > On Wed, 2008-07-30 at 21:09 -0700, Yinghai Lu wrote: >> please check the patches adding dyn_array and nr_irqs #2 > > Why can't we use a radix tree like powerpc does? Unless I am mistaken the ppc uses the radix tree for something different. We don't have any architecture in the kernel to my knowledge that doesn't use an array of irq_desc entries. Killing the array of irq_desc entries and along with it NR_IRQS is what needs to happen. Eric ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 0/7] dyn_array support 2008-07-30 19:10 ` [PATCH 0/7] dyn_array support Yinghai Lu ` (7 preceding siblings ...) 2008-07-31 4:09 ` [PATCH 0/3] dyn_array support #2 Yinghai Lu @ 2008-08-01 20:13 ` Eric W. Biederman 8 siblings, 0 replies; 44+ messages in thread From: Eric W. Biederman @ 2008-08-01 20:13 UTC (permalink / raw) To: Yinghai Lu Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel Ugh. Looks like I forgot to hit send on this. Yinghai Lu <yhlu.kernel@gmail.com> writes: > please check the patches adding dyn_array and nr_irqs YH thank you for working on this. To fix the post rc1 regression I believe your patch series is very much overkill. We need to fix this but the bug should be fixed first by restoring the old heuristics for NR_IRQS. I will carefully look at your first patch and see if it successfully restores the old heuristics, I don't think it quite does. I very much do not like this approach of introducing nr_irqs instead of NR_IRQS. It does not kill NR_IRQS it just renames it and it does not appear to me to solve the real issues, and it seems to entrench some current mistakes instead of clean them up. When I said NR_IRQS must die I meant the concept not the spelling. Having a fixed sized array is only part of it. We actually use that array very sparsely. So even having an array of irq_desc structures is painful. Further we want to user our irq numbers sparsely so that we can have a stable irq numbers even for things such as msis. Outside of the arch specific code and the irq implementation there are currently only 40 mentions of NR_IRQS, and only 7 mentions of NR_IRQS as an array size. git-ls-files | grep -v '^arch' | grep -v '^include/asm' | \ grep -v '^kernel/irq' | grep -v 'drivers/xen/events.c' | \ xargs grep '[^A-Za-z0-9_]NR_IRQS[^A-Za-z0-9_]' | wc -l There is little to no excuse for the generic code to be using NR_IRQS. The usage in /dev/random should be moved in some form into irq_desc. The usage in the serial code and in intr_remapping are failures to use current best practices. For most of the rest simply introducing an irq valid helper function would solve the issue. Further once we have killed the usage of NR_IRQS outside of the arch code. We don't need to introduce new infrastructure. We can call alloc_bootmem as appropriate, and we can consider important things such as NUMA affinity with the irq controllers, and where we expect the irqs to be serviced. Plus we don't have to allocate anything beyond the gsi or their mptable equivalents until someone actually uses the msi or htirq interrupt. Which means we can be a lot leaner, allocating precisely the irqs we need, and a lot more efficient with NUMA affinity and by allocating irqs as they show up. Eric ^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH] x86: 64bit support more than 256 irq v2
@ 2008-08-02 2:02 Yinghai Lu
2008-08-02 2:16 ` Yinghai Lu
2008-08-03 5:09 ` Eric W. Biederman
0 siblings, 2 replies; 44+ messages in thread
From: Yinghai Lu @ 2008-08-02 2:02 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman,
Dhaval Giani, Mike Travis, Andrew Morton
Cc: linux-kernel, Yinghai Lu
Dhaval Giani got:
kernel BUG at arch/x86/kernel/io_apic_64.c:357!
invalid opcode: 0000 [1] SMP
CPU 24
...
his system (x3950) has 8 ioapic, irq > 256
caused by
commit 9b7dc567d03d74a1fbae84e88949b6a60d922d82
Author: Thomas Gleixner <tglx@linutronix.de>
Date: Fri May 2 20:10:09 2008 +0200
x86: unify interrupt vector defines
The interrupt vector defines are copied 4 times around with minimal
differences. Move them all into asm-x86/irq_vectors.h
because 64bit allow same vector for different cpu to serve different irq
need to create that array dynamically later
v2: change NR_IRQS to 1024
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Tested-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
---
include/asm-x86/irq_vectors.h | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
Index: linux-2.6/include/asm-x86/irq_vectors.h
===================================================================
--- linux-2.6.orig/include/asm-x86/irq_vectors.h
+++ linux-2.6/include/asm-x86/irq_vectors.h
@@ -113,28 +113,22 @@
# if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_PARAVIRT) || defined(CONFIG_X86_VISWS)
-# define NR_IRQS 224
-
-# if (224 >= 32 * NR_CPUS)
-# define NR_IRQ_VECTORS NR_IRQS
-# else
-# define NR_IRQ_VECTORS (32 * NR_CPUS)
-# endif
+#define NR_IRQS 1024
# else /* IO_APIC || PARAVIRT */
# define NR_IRQS 16
-# define NR_IRQ_VECTORS NR_IRQS
# endif
#else /* !VISWS && !VOYAGER */
# define NR_IRQS 224
-# define NR_IRQ_VECTORS NR_IRQS
#endif /* VISWS */
+#define NR_IRQ_VECTORS NR_IRQS
+
/* Voyager specific defines */
/* These define the CPIs we use in linux */
#define VIC_CPI_LEVEL0 0
^ permalink raw reply [flat|nested] 44+ messages in thread* Re: [PATCH] x86: 64bit support more than 256 irq v2 2008-08-02 2:02 [PATCH] x86: 64bit support more than 256 irq v2 Yinghai Lu @ 2008-08-02 2:16 ` Yinghai Lu 2008-08-02 2:58 ` Eric W. Biederman 2008-08-03 5:09 ` Eric W. Biederman 1 sibling, 1 reply; 44+ messages in thread From: Yinghai Lu @ 2008-08-02 2:16 UTC (permalink / raw) To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Eric W. Biederman, Dhaval Giani, Mike Travis, Andrew Morton Cc: linux-kernel, Yinghai Lu On Fri, Aug 1, 2008 at 7:02 PM, Yinghai Lu <yhlu.kernel@gmail.com> wrote: > Dhaval Giani got: > kernel BUG at arch/x86/kernel/io_apic_64.c:357! > invalid opcode: 0000 [1] SMP > CPU 24 > ... > > his system (x3950) has 8 ioapic, irq > 256 > > caused by > commit 9b7dc567d03d74a1fbae84e88949b6a60d922d82 > Author: Thomas Gleixner <tglx@linutronix.de> > Date: Fri May 2 20:10:09 2008 +0200 > > x86: unify interrupt vector defines > > The interrupt vector defines are copied 4 times around with minimal > differences. Move them all into asm-x86/irq_vectors.h > > because 64bit allow same vector for different cpu to serve different irq > > need to create that array dynamically later > > v2: change NR_IRQS to 1024 > > Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> > Tested-by: Dhaval Giani <dhaval@linux.vnet.ibm.com> this is for http://bugzilla.kernel.org/show_bug.cgi?id=11201 but need SGI guys to verify in their system. they like to have NR_IRQS to be 224 otherwise we need to use dyn_array solution or wait for Eric come out dyn irq_desc/irq_cfg YH ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] x86: 64bit support more than 256 irq v2 2008-08-02 2:16 ` Yinghai Lu @ 2008-08-02 2:58 ` Eric W. Biederman 2008-08-02 3:11 ` Yinghai Lu 2008-08-04 13:20 ` Mike Travis 0 siblings, 2 replies; 44+ messages in thread From: Eric W. Biederman @ 2008-08-02 2:58 UTC (permalink / raw) To: Yinghai Lu Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel "Yinghai Lu" <yhlu.kernel@gmail.com> writes: > On Fri, Aug 1, 2008 at 7:02 PM, Yinghai Lu <yhlu.kernel@gmail.com> wrote: >> Dhaval Giani got: >> kernel BUG at arch/x86/kernel/io_apic_64.c:357! >> invalid opcode: 0000 [1] SMP >> CPU 24 >> ... >> >> his system (x3950) has 8 ioapic, irq > 256 >> >> caused by >> commit 9b7dc567d03d74a1fbae84e88949b6a60d922d82 >> Author: Thomas Gleixner <tglx@linutronix.de> >> Date: Fri May 2 20:10:09 2008 +0200 >> >> x86: unify interrupt vector defines >> >> The interrupt vector defines are copied 4 times around with minimal >> differences. Move them all into asm-x86/irq_vectors.h >> >> because 64bit allow same vector for different cpu to serve different irq >> >> need to create that array dynamically later >> >> v2: change NR_IRQS to 1024 >> >> Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> >> Tested-by: Dhaval Giani <dhaval@linux.vnet.ibm.com> > > this is for > http://bugzilla.kernel.org/show_bug.cgi?id=11201 > > but need SGI guys to verify in their system. they like to have NR_IRQS to be 224 There was a patch that came out a while ago that set NR_IRQS as NR_IOAPICS*32 from SGI. Where that got to I don't recall. Eric ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] x86: 64bit support more than 256 irq v2 2008-08-02 2:58 ` Eric W. Biederman @ 2008-08-02 3:11 ` Yinghai Lu 2008-08-02 3:37 ` Eric W. Biederman 2008-08-04 13:20 ` Mike Travis 1 sibling, 1 reply; 44+ messages in thread From: Yinghai Lu @ 2008-08-02 3:11 UTC (permalink / raw) To: Eric W. Biederman Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel On Fri, Aug 1, 2008 at 7:58 PM, Eric W. Biederman <ebiederm@xmission.com> wrote: > "Yinghai Lu" <yhlu.kernel@gmail.com> writes: > >> On Fri, Aug 1, 2008 at 7:02 PM, Yinghai Lu <yhlu.kernel@gmail.com> wrote: >>> Dhaval Giani got: >>> kernel BUG at arch/x86/kernel/io_apic_64.c:357! >>> invalid opcode: 0000 [1] SMP >>> CPU 24 >>> ... >>> >>> his system (x3950) has 8 ioapic, irq > 256 .. > > There was a patch that came out a while ago that set NR_IRQS as NR_IOAPICS*32 from > SGI. Where that got to I don't recall. #ifdef CONFIG_X86_32 # define MAX_IO_APICS 64 #else # define MAX_IO_APICS 128 # define MAX_LOCAL_APIC 32768 #endif so they can take 128*32 = 4096? YH ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] x86: 64bit support more than 256 irq v2 2008-08-02 3:11 ` Yinghai Lu @ 2008-08-02 3:37 ` Eric W. Biederman 0 siblings, 0 replies; 44+ messages in thread From: Eric W. Biederman @ 2008-08-02 3:37 UTC (permalink / raw) To: Yinghai Lu Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel "Yinghai Lu" <yhlu.kernel@gmail.com> writes: > On Fri, Aug 1, 2008 at 7:58 PM, Eric W. Biederman <ebiederm@xmission.com> wrote: >> "Yinghai Lu" <yhlu.kernel@gmail.com> writes: >> >>> On Fri, Aug 1, 2008 at 7:02 PM, Yinghai Lu <yhlu.kernel@gmail.com> wrote: >>>> Dhaval Giani got: >>>> kernel BUG at arch/x86/kernel/io_apic_64.c:357! >>>> invalid opcode: 0000 [1] SMP >>>> CPU 24 >>>> ... >>>> >>>> his system (x3950) has 8 ioapic, irq > 256 > .. >> >> There was a patch that came out a while ago that set NR_IRQS as NR_IOAPICS*32 > from >> SGI. Where that got to I don't recall. > > #ifdef CONFIG_X86_32 > # define MAX_IO_APICS 64 > #else > # define MAX_IO_APICS 128 > # define MAX_LOCAL_APIC 32768 > #endif > > so they can take 128*32 = 4096? Yes. The real problem was just the complete explosion of irqs on SGI machines that have paltry I/O to the outside world compared to their cpu count. Have 131072 irqs seemed a little much for them. It is all a game of tuning heuristics right now, and if we can totally kill NR_IRQS it all goes away. But that is an issue to solve before the next merge window not to kill the regression. Eric ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] x86: 64bit support more than 256 irq v2 2008-08-02 2:58 ` Eric W. Biederman 2008-08-02 3:11 ` Yinghai Lu @ 2008-08-04 13:20 ` Mike Travis 2008-08-04 18:16 ` Yinghai Lu 1 sibling, 1 reply; 44+ messages in thread From: Mike Travis @ 2008-08-04 13:20 UTC (permalink / raw) To: Eric W. Biederman Cc: Yinghai Lu, Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Andrew Morton, linux-kernel, Alan Mayer Eric W. Biederman wrote: > "Yinghai Lu" <yhlu.kernel@gmail.com> writes: > >> On Fri, Aug 1, 2008 at 7:02 PM, Yinghai Lu <yhlu.kernel@gmail.com> wrote: >>> Dhaval Giani got: >>> kernel BUG at arch/x86/kernel/io_apic_64.c:357! >>> invalid opcode: 0000 [1] SMP >>> CPU 24 >>> ... >>> >>> his system (x3950) has 8 ioapic, irq > 256 >>> >>> caused by >>> commit 9b7dc567d03d74a1fbae84e88949b6a60d922d82 >>> Author: Thomas Gleixner <tglx@linutronix.de> >>> Date: Fri May 2 20:10:09 2008 +0200 >>> >>> x86: unify interrupt vector defines >>> >>> The interrupt vector defines are copied 4 times around with minimal >>> differences. Move them all into asm-x86/irq_vectors.h >>> >>> because 64bit allow same vector for different cpu to serve different irq >>> >>> need to create that array dynamically later >>> >>> v2: change NR_IRQS to 1024 >>> >>> Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> >>> Tested-by: Dhaval Giani <dhaval@linux.vnet.ibm.com> >> this is for >> http://bugzilla.kernel.org/show_bug.cgi?id=11201 >> >> but need SGI guys to verify in their system. they like to have NR_IRQS to be 224 > > There was a patch that came out a while ago that set NR_IRQS as NR_IOAPICS*32 from > SGI. Where that got to I don't recall. > > Eric That was from Alan ... I'll Cc: him. Here's an early copy (not sure if this was the final one though.) >From: Alan Mayer <ajm@sgi.com> Subject: [PATCH] x86_64: resize NR_IRQS for large machines On machines with very large numbers of cpus, tables that are dimensioned by NR_IRQS get very large, especially the irq_desc table. They are also very sparsely used. When the cpu count is > MAX_IO_APICS, use MAX_IO_APICS to set NR_IRQS, otherwise use NR_CPUS. Reviewed-by: Christoph Lameter <clameter@sgi.com> Signed-off-by: Alan Mayer <ajm@sgi.com> Index: v2.6.25-rc6/include/asm-x86/irq_64.h =================================================================== --- v2.6.25-rc6.orig/include/asm-x86/irq_64.h 2008-03-19 16:52:52.000000000 -0500 +++ v2.6.25-rc6/include/asm-x86/irq_64.h 2008-03-20 16:46:51.000000000 -0500 @@ -10,6 +10,10 @@ * <tomsoft@informatik.tu-chemnitz.de> */ +#if !defined(MAX_IO_APICS) +#include <asm/apicdef.h> +#endif + #define TIMER_IRQ 0 /* @@ -31,7 +35,11 @@ #define FIRST_SYSTEM_VECTOR 0xef /* duplicated in hw_irq.h */ -#define NR_IRQS (NR_VECTORS + (32 *NR_CPUS)) +#if NR_CPUS < MAX_IO_APICS +#define NR_IRQS (NR_VECTORS + (32 * NR_CPUS)) +#else +#define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS)) +#endif #define NR_IRQ_VECTORS NR_IRQS static __inline__ int irq_canonicalize(int irq) Index: v2.6.25-rc6/include/linux/kernel_stat.h =================================================================== --- v2.6.25-rc6.orig/include/linux/kernel_stat.h 2008-03-19 16:53:00.000000000 -0500 +++ v2.6.25-rc6/include/linux/kernel_stat.h 2008-03-20 11:12:27.000000000 -0500 @@ -1,11 +1,11 @@ #ifndef _LINUX_KERNEL_STAT_H #define _LINUX_KERNEL_STAT_H -#include <asm/irq.h> #include <linux/smp.h> #include <linux/threads.h> #include <linux/percpu.h> #include <linux/cpumask.h> +#include <asm/irq.h> #include <asm/cputime.h> /* ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] x86: 64bit support more than 256 irq v2 2008-08-04 13:20 ` Mike Travis @ 2008-08-04 18:16 ` Yinghai Lu 0 siblings, 0 replies; 44+ messages in thread From: Yinghai Lu @ 2008-08-04 18:16 UTC (permalink / raw) To: Mike Travis Cc: Eric W. Biederman, Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Andrew Morton, linux-kernel, Alan Mayer On Mon, Aug 4, 2008 at 6:20 AM, Mike Travis <travis@sgi.com> wrote: > Eric W. Biederman wrote: >> "Yinghai Lu" <yhlu.kernel@gmail.com> writes: >> >>> On Fri, Aug 1, 2008 at 7:02 PM, Yinghai Lu <yhlu.kernel@gmail.com> wrote: >>>> Dhaval Giani got: >>>> kernel BUG at arch/x86/kernel/io_apic_64.c:357! >>>> invalid opcode: 0000 [1] SMP >>>> CPU 24 >>>> ... >>>> >>>> his system (x3950) has 8 ioapic, irq > 256 >>>> >>>> caused by >>>> commit 9b7dc567d03d74a1fbae84e88949b6a60d922d82 >>>> Author: Thomas Gleixner <tglx@linutronix.de> >>>> Date: Fri May 2 20:10:09 2008 +0200 >>>> >>>> x86: unify interrupt vector defines >>>> >>>> The interrupt vector defines are copied 4 times around with minimal >>>> differences. Move them all into asm-x86/irq_vectors.h >>>> >>>> because 64bit allow same vector for different cpu to serve different irq >>>> >>>> need to create that array dynamically later >>>> >>>> v2: change NR_IRQS to 1024 >>>> >>>> Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> >>>> Tested-by: Dhaval Giani <dhaval@linux.vnet.ibm.com> >>> this is for >>> http://bugzilla.kernel.org/show_bug.cgi?id=11201 >>> >>> but need SGI guys to verify in their system. they like to have NR_IRQS to be 224 >> >> There was a patch that came out a while ago that set NR_IRQS as NR_IOAPICS*32 from >> SGI. Where that got to I don't recall. >> >> Eric > > That was from Alan ... I'll Cc: him. Here's an early copy (not sure if > this was the final one though.) > > >>From: Alan Mayer <ajm@sgi.com> > Subject: [PATCH] x86_64: resize NR_IRQS for large machines > > On machines with very large numbers of cpus, tables that are dimensioned > by NR_IRQS get very large, especially the irq_desc table. They are also > very sparsely used. When the cpu count is > MAX_IO_APICS, use MAX_IO_APICS > to set NR_IRQS, otherwise use NR_CPUS. > > Reviewed-by: Christoph Lameter <clameter@sgi.com> > > Signed-off-by: Alan Mayer <ajm@sgi.com> > Index: v2.6.25-rc6/include/asm-x86/irq_64.h > =================================================================== > --- v2.6.25-rc6.orig/include/asm-x86/irq_64.h 2008-03-19 16:52:52.000000000 -0500 > +++ v2.6.25-rc6/include/asm-x86/irq_64.h 2008-03-20 16:46:51.000000000 -0500 > @@ -10,6 +10,10 @@ > * <tomsoft@informatik.tu-chemnitz.de> > */ > > +#if !defined(MAX_IO_APICS) > +#include <asm/apicdef.h> > +#endif > + > #define TIMER_IRQ 0 > > /* > @@ -31,7 +35,11 @@ > > #define FIRST_SYSTEM_VECTOR 0xef /* duplicated in hw_irq.h */ > > -#define NR_IRQS (NR_VECTORS + (32 *NR_CPUS)) > +#if NR_CPUS < MAX_IO_APICS > +#define NR_IRQS (NR_VECTORS + (32 * NR_CPUS)) > +#else > +#define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS)) > +#endif > #define NR_IRQ_VECTORS NR_IRQS > > static __inline__ int irq_canonicalize(int irq) > Index: v2.6.25-rc6/include/linux/kernel_stat.h > =================================================================== > --- v2.6.25-rc6.orig/include/linux/kernel_stat.h 2008-03-19 16:53:00.000000000 -0500 > +++ v2.6.25-rc6/include/linux/kernel_stat.h 2008-03-20 11:12:27.000000000 -0500 > @@ -1,11 +1,11 @@ > #ifndef _LINUX_KERNEL_STAT_H > #define _LINUX_KERNEL_STAT_H > > -#include <asm/irq.h> > #include <linux/smp.h> > #include <linux/threads.h> > #include <linux/percpu.h> > #include <linux/cpumask.h> > +#include <asm/irq.h> > #include <asm/cputime.h> > > /* > so this one have right sequence... could add sth say why need special including sequence... YH ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH] x86: 64bit support more than 256 irq v2 2008-08-02 2:02 [PATCH] x86: 64bit support more than 256 irq v2 Yinghai Lu 2008-08-02 2:16 ` Yinghai Lu @ 2008-08-03 5:09 ` Eric W. Biederman 1 sibling, 0 replies; 44+ messages in thread From: Eric W. Biederman @ 2008-08-03 5:09 UTC (permalink / raw) To: Yinghai Lu Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Dhaval Giani, Mike Travis, Andrew Morton, linux-kernel Yinghai Lu <yhlu.kernel@gmail.com> writes: > Dhaval Giani got: > kernel BUG at arch/x86/kernel/io_apic_64.c:357! > invalid opcode: 0000 [1] SMP > CPU 24 > ... > > his system (x3950) has 8 ioapic, irq > 256 > > caused by > commit 9b7dc567d03d74a1fbae84e88949b6a60d922d82 > Author: Thomas Gleixner <tglx@linutronix.de> > Date: Fri May 2 20:10:09 2008 +0200 > > x86: unify interrupt vector defines > > The interrupt vector defines are copied 4 times around with minimal > differences. Move them all into asm-x86/irq_vectors.h > > because 64bit allow same vector for different cpu to serve different irq > > need to create that array dynamically later YH Thank you for splitting this out. This still doesn't restore the pre merge NR_IRQS heuristic. So I don't think it is a proper regression fix. Eric ^ permalink raw reply [flat|nested] 44+ messages in thread
end of thread, other threads:[~2008-08-04 18:20 UTC | newest] Thread overview: 44+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-07-29 21:14 [PATCH] x86: 64bit support more than 256 irq v2 Yinghai Lu 2008-07-29 22:16 ` Yinghai Lu 2008-07-29 23:22 ` Eric W. Biederman 2008-07-30 4:38 ` RFC [PATCH] x86: introduce nr_irqs for 64bit Yinghai Lu 2008-07-30 10:09 ` Ingo Molnar 2008-07-30 10:16 ` Yinghai Lu 2008-07-30 12:58 ` Mike Travis 2008-07-30 10:11 ` [PATCH] x86: introduce nr_irqs for 64bit v2 Yinghai Lu 2008-07-30 19:10 ` [PATCH 0/7] dyn_array support Yinghai Lu 2008-07-30 19:13 ` [PATCH 2/7] x86: introduce nr_irqs for 64bit v3 Yinghai Lu 2008-07-30 19:16 ` [PATCH 5/7] pci: make irq2_iommu to use dyn_array Yinghai Lu 2008-07-30 19:18 ` [PATCH 7/7] x86: make 64bit support dyn_array Yinghai Lu 2008-07-30 19:27 ` [PATCH 1/7] x86: 64bit support more than 256 irq v1 Yinghai Lu 2008-07-30 19:37 ` [PATCH 3/7] add dyn_array support Yinghai Lu 2008-07-30 19:40 ` [PATCH 6/7] irq: make irq_desc to use dyn_array Yinghai Lu 2008-07-30 19:40 ` [PATCH 4/7] random: make irq_timer_state " Yinghai Lu 2008-07-31 4:09 ` [PATCH 0/3] dyn_array support #2 Yinghai Lu 2008-07-31 4:10 ` [PATCH 1/3] serial: change irq_lists to use dyn_array Yinghai Lu 2008-07-31 5:58 ` Eric W. Biederman 2008-07-31 8:26 ` [PATCH] serial: change remove NR_IRQS in 8250.c Yinghai Lu 2008-07-31 11:50 ` Eric W. Biederman 2008-07-31 13:57 ` Alan Cox 2008-07-31 18:10 ` Eric W. Biederman 2008-07-31 23:15 ` Alan Cox 2008-08-01 3:20 ` Yinghai Lu 2008-07-31 4:11 ` [PATCH 2/3] add per_cpu_dyn_array support Yinghai Lu 2008-07-31 4:12 ` [PATCH 3/3] irq: make irqs in kernel stat use per_cpu_dyn_array Yinghai Lu 2008-07-31 10:14 ` [PATCH] x86 remove irq_vectors_limit.h Yinghai Lu 2008-07-31 16:32 ` [PATCH 0/3] dyn_array support #2 Mike Travis 2008-07-31 18:21 ` Yinghai Lu 2008-07-31 21:51 ` Peter Zijlstra 2008-07-31 22:07 ` Yinghai Lu 2008-07-31 22:25 ` Yinghai Lu 2008-08-01 3:52 ` Yinghai Lu 2008-07-31 22:14 ` Eric W. Biederman 2008-08-01 20:13 ` [PATCH 0/7] dyn_array support Eric W. Biederman -- strict thread matches above, loose matches on Subject: below -- 2008-08-02 2:02 [PATCH] x86: 64bit support more than 256 irq v2 Yinghai Lu 2008-08-02 2:16 ` Yinghai Lu 2008-08-02 2:58 ` Eric W. Biederman 2008-08-02 3:11 ` Yinghai Lu 2008-08-02 3:37 ` Eric W. Biederman 2008-08-04 13:20 ` Mike Travis 2008-08-04 18:16 ` Yinghai Lu 2008-08-03 5:09 ` Eric W. Biederman
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox