x86: 64bit support more than 256 irq v2
Subsystems (15)
PATCH 1/1 x86: 64bit support more than 256 irq v2
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 <[email protected]>
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
--- arch/x86/kernel/io_apic_64.c | 3 ++- include/asm-x86/irq_vectors.h | 14 ++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-)
include/asm-x86/irq_vectors.h +6 -8
@@ -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
arch/x86/kernel/io_apic_64.c +2 -1
@@ -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 {
Quoted 73 lines · Yinghai Lu
Dhaval Giani got:
kernel BUG atarch/x86/kernel/io_apic_64.c:357!
invalid opcode: 0000 [1] SMP
CPU 24Modules 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
commit9b7dc567d03d74a1fbae84e88949b6a60d922d82
Author: Thomas Gleixner <[email protected]>
Date: Fri May 2 20:10:09 2008 +0200x86: unify interrupt vector defines
The interrupt vector defines are copied 4 times around with minimal differences. Move them all into
asm-x86/irq_vectors.h64bit allow same vector for different cpu to serve different irq
Quoted 7 lines
also change next in
irq_pin_listfrom short to int. because for 4096NR_IRQSis 2^(8+12).v2: accoding to Eric W. Biederman, change to
NR_IRQ_VECTORStoNR_IRQS
use NR_VECTORS*NR_CPUS directlyneed 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
Quoted 72 lines · Yinghai Lu
Dhaval Giani got:
kernel BUG atarch/x86/kernel/io_apic_64.c:357!
invalid opcode: 0000 [1] SMP
CPU 24Modules 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 8d90 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
commit9b7dc567d03d74a1fbae84e88949b6a60d922d82
Author: Thomas Gleixner <[email protected]>
Date: Fri May 2 20:10:09 2008 +0200x86: 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
Quoted 7 lines
64bit allow same vector for different cpu to serve different irq
also change next in
irq_pin_listfrom short to int. because for 4096NR_IRQSis 2^(8+12).v2: accoding to Eric W. Biederman, change to
NR_IRQ_VECTORStoNR_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
RFC [PATCH] x86: introduce nr_irqs for 64bit
In reply to Yinghai Luadd DEFINE_DYN_ARRAY for dynamical array support
todo:
1. convert x86 32bit and other arch
2. nr_irqs auto probe via acpi_oem_check?
--- 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(-)
arch/x86/kernel/io_apic_32.c +1 -0
@@ -70,6 +70,7 @@ int timer_through_8259 __initdata;*/ int sis_apic_bug =-1 ; +int nr_irqs =NR_IRQS ;/* * # of IRQ routing registers */
arch/x86/kernel/io_apic_64.c +38 -21
177 lines not on this page · raw message
arch/x86/kernel/irq_64.c +4 -4
@@ -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 ptstack_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 ;
arch/x86/kernel/irqinit_64.c +1 -1
@@ -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 ;
arch/x86/kernel/setup.c +7 -0
@@ -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
arch/x86/kernel/vmlinux_64.lds.S +3 -0
@@ -174,6 +174,9 @@ SECTIONS *(.x86cpuvendor.init) } __x86cpuvendor_end = .; + + DYN_ARRAY_INIT(8) + SECURITY_INIT . = ALIGN(8);
drivers/char/hpet.c +1 -1
@@ -222,7 +222,7 @@ static void hpet_timer_set_irq(struct hpfor (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 ; }
drivers/char/random.c +2 -2
@@ -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 ;/*
drivers/pci/intr_remapping.c +12 -10
@@ -11,18 +11,20 @@ static struct ioapic_scope ir_ioapic[MAXstatic 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, u16int 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, u16int 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_iint 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 *irstruct 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 ; }
drivers/serial/8250.c +5 -3
@@ -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(strucstatic 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);
drivers/serial/serial_core.c +1 -1
@@ -741,7 +741,7 @@ static int uart_set_info(struct uart_staif (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 ;
drivers/xen/events.c +6 -6
@@ -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 ());
fs/proc/proc_misc.c +5 -5
@@ -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; }
include/asm-generic/vmlinux.lds.h +7 -0
@@ -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) = .; \
include/asm-x86/irq.h +4 -0
@@ -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);
include/asm-x86/irq_vectors.h +6 -8
@@ -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
include/linux/init.h +23 -0
@@ -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__ */ /**
include/linux/irq.h +1 -1
@@ -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:
init/main.c +20 -0
@@ -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;
kernel/irq/autoprobe.c +5 -5
@@ -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 lonint 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;
kernel/irq/chip.c +10 -10
@@ -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 irstruct 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, strucstruct 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, unsigunsigned 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, voidstruct 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, structstruct 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 intstruct 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 istruct 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 ;
kernel/irq/handle.c +24 -10
@@ -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); }
kernel/irq/manage.c +8 -8
@@ -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 irqstruct 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 iint 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 *deunsigned 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 ;
kernel/irq/proc.c +1 -1
@@ -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); }
kernel/irq/resend.c +2 -2
@@ -33,8 +33,8 @@ static void resend_irqs(unsigned long arstruct 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 ();
kernel/irq/spurious.c +2 -2
@@ -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;
Re: RFC [PATCH] x86: introduce nr_irqs for 64bit
Quoted 7 lines · Yinghai Lu
add
DEFINE_DYN_ARRAYfor dynamical array supporttodo:
1. convert x86 32bit and other arch
2.nr_irqsauto probe viaacpi_oem_check?Signed-off-by Yinghai Lu <[email protected]>
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
Re: RFC [PATCH] x86: introduce nr_irqs for 64bit
Quoted 17 lines · Ingo Molnar
Quoted 7 lines · Yinghai Lu
add
DEFINE_DYN_ARRAYfor dynamical array supporttodo:
1. convert x86 32bit and other arch
2.nr_irqsauto probe viaacpi_oem_check?Signed-off-by Yinghai Lu <[email protected]>wonderful!
I have one main structural suggestion: could we please keep the
NR_IRQSname, and just change it to dynamic on x86?NR_IRQSis used in 540 places in the kernel, there's no point in touching all that code.
Quoted 5 lines
Also add an
CONFIG_ARCH_HAS_DYNAMIC_NR_IRQSswitch, define it inarch/x86/Kconfigand use it ininclude/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
Re: RFC [PATCH] x86: introduce nr_irqs for 64bit
In reply to Ingo MolnarQuoted 8 lines · Ingo Molnar
Quoted 6 lines · Yinghai Lu
add
DEFINE_DYN_ARRAYfor dynamical array supporttodo:
1. convert x86 32bit and other arch
2.nr_irqsauto probe viaacpi_oem_check?
Quoted 7 lines
Quoted 1 line
Signed-off-by Yinghai Lu <[email protected]>wonderful!
I have one main structural suggestion: could we please keep the
NR_IRQSname, and just change it to dynamic on x86?NR_IRQSis used in 540 places in the kernel, there's no point in touching all that code.
Good thought.
Quoted 3 lines
Also add an
CONFIG_ARCH_HAS_DYNAMIC_NR_IRQSswitch, define it inarch/x86/Kconfigand use it ininclude/linux/irq.h.
It could also revert DEFINE_DYN_ARRAY to a fixed array for more compact code in small machines.
Thanks,
Mike
Quoted 5 lines
This will create far less migration pain than the widespread rename. That will also solve the "what about the other architectures" question.
Ingo
PATCH 1/1 x86: introduce nr_irqs for 64bit v2
In reply to Yinghai Luadd 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
--- 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(-)
arch/x86/kernel/io_apic_32.c +10 -10
@@ -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_cpuint 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 )
arch/x86/kernel/io_apic_64.c +36 -21
175 lines not on this page · raw message
arch/x86/kernel/irq_32.c +4 -4
@@ -226,7 +226,7 @@ unsigned int do_IRQ(struct pt_regs *regsint 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 ;
arch/x86/kernel/irq_64.c +4 -4
@@ -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 ptstack_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 ;
arch/x86/kernel/irqinit_32.c +1 -1
@@ -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))
arch/x86/kernel/irqinit_64.c +1 -1
@@ -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 ;
arch/x86/kernel/setup.c +8 -0
@@ -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
arch/x86/kernel/vmlinux_32.lds.S +1 -0
@@ -145,6 +145,7 @@ SECTIONS *(.x86cpuvendor.init) __x86cpuvendor_end = .; } + DYN_ARRAY_INIT(8) SECURITY_INIT . = ALIGN(4); .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
arch/x86/kernel/vmlinux_64.lds.S +3 -0
@@ -174,6 +174,9 @@ SECTIONS *(.x86cpuvendor.init) } __x86cpuvendor_end = .; + + DYN_ARRAY_INIT(8) + SECURITY_INIT . = ALIGN(8);
drivers/char/hpet.c +1 -1
@@ -222,7 +222,7 @@ static void hpet_timer_set_irq(struct hpfor (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 ; }
drivers/char/random.c +8 -2
@@ -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 ;/*
drivers/char/vr41xx_giu.c +1 -1
@@ -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);
drivers/net/3c59x.c +2 -2
@@ -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(strucif (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);
drivers/net/hamradio/baycom_ser_fdx.c +2 -2
@@ -416,10 +416,10 @@ static int ser12_open(struct net_deviceif (!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 ) {
drivers/net/hamradio/scc.c +3 -3
@@ -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_deviif (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 ();
drivers/net/wan/sbni.c +1 -1
@@ -318,7 +318,7 @@ sbni_pci_probe( struct net_device *devcontinue ; } -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"
drivers/pci/intr_remapping.c +12 -10
@@ -11,18 +11,20 @@ static struct ioapic_scope ir_ioapic[MAXstatic 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, u16int 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, u16int 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_iint 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 *irstruct 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 ; }
drivers/pcmcia/at91_cf.c +1 -1
@@ -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)
drivers/pcmcia/vrc4171_card.c +1 -1
@@ -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 !=',' )
drivers/rtc/rtc-vr41xx.c +2 -2
@@ -360,7 +360,7 @@ static int __devinit rtc_probe(struct plspin_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,
drivers/scsi/aha152x.c +1 -1
@@ -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
drivers/serial/8250.c +2 -2
@@ -2433,7 +2433,7 @@ static void serial8250_config_port(strucstatic 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);
drivers/serial/amba-pl010.c +1 -1
@@ -512,7 +512,7 @@ static int pl010_verify_port(struct uartint 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 ;
drivers/serial/amba-pl011.c +1 -1
@@ -572,7 +572,7 @@ static int pl010_verify_port(struct uartint 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 ;
drivers/serial/cpm_uart/cpm_uart_core.c +1 -1
@@ -589,7 +589,7 @@ static int cpm_uart_verify_port(struct uif (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 ;
drivers/serial/m32r_sio.c +2 -2
@@ -922,7 +922,7 @@ static void m32r_sio_config_port(structstatic 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);
drivers/serial/serial_core.c +1 -1
@@ -741,7 +741,7 @@ static int uart_set_info(struct uart_staif (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 ;
drivers/serial/serial_lh7a40x.c +1 -1
@@ -460,7 +460,7 @@ static int lh7a40xuart_verify_port (struif (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 ;
drivers/serial/sh-sci.c +1 -1
@@ -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.. */
drivers/serial/ucc_uart.c +1 -1
@@ -1066,7 +1066,7 @@ static int qe_uart_verify_port(struct uaif (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 )
drivers/xen/events.c +6 -6
@@ -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 ());
fs/proc/proc_misc.c +5 -5
@@ -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; }
include/asm-generic/vmlinux.lds.h +7 -0
@@ -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) = .; \
include/asm-x86/irq.h +3 -0
@@ -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);
include/asm-x86/irq_vectors.h +6 -8
@@ -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
include/linux/init.h +23 -0
@@ -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__ */ /**
include/linux/irq.h +6 -0
@@ -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:
init/main.c +21 -0
@@ -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;
kernel/irq/autoprobe.c +5 -5
@@ -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 lonint 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;
kernel/irq/chip.c +10 -10
@@ -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 irstruct 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, strucstruct 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, unsigunsigned 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, voidstruct 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, structstruct 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 intstruct 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 istruct 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 ;
kernel/irq/handle.c +33 -1
@@ -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); }
kernel/irq/manage.c +8 -8
@@ -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 irqstruct 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 iint 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 *deunsigned 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 ;
kernel/irq/proc.c +1 -1
@@ -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); }
kernel/irq/resend.c +2 -2
@@ -33,8 +33,8 @@ static void resend_irqs(unsigned long arstruct 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 ();
kernel/irq/spurious.c +2 -2
@@ -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;
cover dyn_array support
please check the patches adding dyn_array and nr_irqs
Thanks
YH
PATCH 1/7 x86: 64bit support more than 256 irq v1
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 <[email protected]>
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
--- include/asm-x86/irq_vectors.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
include/asm-x86/irq_vectors.h +6 -8
@@ -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
PATCH 2/7 x86: introduce nr_irqs for 64bit v3
In reply to Yinghai Luadd 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
---
--- 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(-)
arch/x86/kernel/io_apic_32.c +14 -12
@@ -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 intif (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_cpuint 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 )
arch/x86/kernel/io_apic_64.c +17 -16
@@ -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(unsignedint 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(unsigneint 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_intstruct 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 )
arch/x86/kernel/irq_32.c +4 -4
@@ -226,7 +226,7 @@ unsigned int do_IRQ(struct pt_regs *regsint 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 ;
arch/x86/kernel/irq_64.c +4 -4
@@ -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 ptstack_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 ;
arch/x86/kernel/irqinit_32.c +1 -1
@@ -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))
arch/x86/kernel/irqinit_64.c +1 -1
@@ -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 ;
drivers/char/hpet.c +1 -1
@@ -222,7 +222,7 @@ static void hpet_timer_set_irq(struct hpfor (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 ; }
drivers/char/random.c +2 -2
@@ -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 ;/*
drivers/char/vr41xx_giu.c +1 -1
@@ -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);
drivers/net/3c59x.c +2 -2
@@ -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(strucif (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);
drivers/net/hamradio/baycom_ser_fdx.c +2 -2
@@ -416,10 +416,10 @@ static int ser12_open(struct net_deviceif (!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 ) {
drivers/net/hamradio/scc.c +3 -3
@@ -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_deviif (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 ();
drivers/net/wan/sbni.c +1 -1
@@ -318,7 +318,7 @@ sbni_pci_probe( struct net_device *devcontinue ; } -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"
drivers/pci/intr_remapping.c +8 -8
@@ -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, u16int 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, u16int 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_iint 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 *irstruct 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 ; }
drivers/pcmcia/at91_cf.c +1 -1
@@ -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)
drivers/pcmcia/vrc4171_card.c +1 -1
@@ -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 !=',' )
drivers/rtc/rtc-vr41xx.c +2 -2
@@ -360,7 +360,7 @@ static int __devinit rtc_probe(struct plspin_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,
drivers/scsi/aha152x.c +1 -1
@@ -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
drivers/serial/8250.c +2 -2
@@ -2433,7 +2433,7 @@ static void serial8250_config_port(strucstatic 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);
drivers/serial/amba-pl010.c +1 -1
@@ -512,7 +512,7 @@ static int pl010_verify_port(struct uartint 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 ;
drivers/serial/amba-pl011.c +1 -1
@@ -572,7 +572,7 @@ static int pl010_verify_port(struct uartint 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 ;
drivers/serial/cpm_uart/cpm_uart_core.c +1 -1
@@ -589,7 +589,7 @@ static int cpm_uart_verify_port(struct uif (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 ;
drivers/serial/m32r_sio.c +2 -2
@@ -922,7 +922,7 @@ static void m32r_sio_config_port(structstatic 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);
drivers/serial/serial_core.c +1 -1
@@ -741,7 +741,7 @@ static int uart_set_info(struct uart_staif (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 ;
drivers/serial/serial_lh7a40x.c +1 -1
@@ -460,7 +460,7 @@ static int lh7a40xuart_verify_port (struif (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 ;
drivers/serial/sh-sci.c +1 -1
@@ -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.. */
drivers/serial/ucc_uart.c +1 -1
@@ -1066,7 +1066,7 @@ static int qe_uart_verify_port(struct uaif (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 )
drivers/xen/events.c +6 -6
@@ -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 ());
fs/proc/proc_misc.c +5 -5
@@ -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; }
include/asm-x86/irq.h +3 -0
@@ -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);
include/linux/irq.h +2 -0
@@ -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);
kernel/irq/autoprobe.c +5 -5
@@ -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 lonint 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;
kernel/irq/chip.c +10 -10
@@ -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 irstruct 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, strucstruct 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, unsigunsigned 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, voidstruct 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, structstruct 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 intstruct 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 istruct 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 ;
kernel/irq/handle.c +2 -1
@@ -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); }
kernel/irq/manage.c +8 -8
@@ -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 irqstruct 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 iint 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 *deunsigned 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 ;
kernel/irq/proc.c +1 -1
@@ -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); }
kernel/irq/resend.c +2 -2
@@ -33,8 +33,8 @@ static void resend_irqs(unsigned long arstruct 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 ();
kernel/irq/spurious.c +2 -2
@@ -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;
PATCH 3/7 add dyn_array support
In reply to Yinghai Lu[
so could put some crazy big array in bootmem in init stage.
use CONFIG_HAVE_DYN_ARRAY to enable it or not
--- include/asm-generic/vmlinux.lds.h | 7 +++++++ include/linux/init.h | 23 +++++++++++++++++++++++ init/main.c | 25 +++++++++++++++++++++++++ 3 files changed, 55 insertions(+)
include/asm-generic/vmlinux.lds.h +7 -0
@@ -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) = .; \
include/linux/init.h +23 -0
@@ -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__ */ /**
init/main.c +25 -0
@@ -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(voidprintk (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 ();
PATCH 4/7 random: make irq_timer_state to use dyn_array
In reply to Yinghai Lu--- drivers/char/random.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/char/random.c +6 -0
@@ -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
PATCH 5/7 pci: make irq2_iommu to use dyn_array
In reply to Yinghai Lu--- drivers/pci/intr_remapping.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/pci/intr_remapping.c +4 -2
@@ -11,12 +11,14 @@ static struct ioapic_scope ir_ioapic[MAXstatic 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);
PATCH 6/7 irq: make irq_desc to use dyn_array
In reply to Yinghai Lu--- include/linux/irq.h | 4 ++++ kernel/irq/handle.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+)
include/linux/irq.h +4 -0
@@ -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:
kernel/irq/handle.c +31 -0
@@ -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?
PATCH 7/7 x86: make 64bit support dyn_array
In reply to Yinghai Luset nr_irqs according to nr_cpu_ids, so could get small footprint when use big kernel.
--- 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(-)
arch/Kconfig +2 -0
@@ -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
arch/x86/Kconfig +1 -0
@@ -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
arch/x86/kernel/io_apic_64.c +21 -7
@@ -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;
arch/x86/kernel/setup.c +6 -0
@@ -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
arch/x86/kernel/vmlinux_64.lds.S +3 -0
@@ -174,6 +174,9 @@ SECTIONS *(.x86cpuvendor.init) } __x86cpuvendor_end = .; + + DYN_ARRAY_INIT(8) + SECURITY_INIT . = ALIGN(8);
cover dyn_array support #2
In reply to Yinghai Luplease check the patches adding dyn_array and nr_irqs #2
Thanks
YH
PATCH 1/3 serial: change irq_lists to use dyn_array
--- drivers/serial/8250.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/serial/8250.c +5 -0
@@ -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.
Re: [PATCH 1/3] serial: change irq_lists to use dyn_array
Quoted 1 line · Yinghai Lu
Signed-off-by Yinghai Lu <[email protected]>
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
PATCH 1/1 serial: change remove NR_IRQS in 8250.c
In reply to Yinghai Lureplace
[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
--- drivers/serial/8250.c | 73 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 6 deletions(-)
drivers/serial/8250.c +67 -6
@@ -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(structstatic 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)
Re: [PATCH] serial: change remove NR_IRQS in 8250.c
Quoted 4 lines
replace
[PATCH] serial: changeirq_liststo usedyn_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
Re: [PATCH] serial: change remove NR_IRQS in 8250.c
Quoted 7 lines · On Thu, 31 Jul 2008 04:50:21 -0700 [email protected] (Eric W. Biederman)…
Quoted 4 lines
replace
[PATCH] serial: changeirq_liststo usedyn_array
use small array with index to handle irq locking for serial port hope 32 slot is enoughCould you size this array by
NR_UARTS(our worst case usage) and placeirq_noin structirq_info?
NR_UARTS is likely to go away in time so don't get attached to it
Re: [PATCH] serial: change remove NR_IRQS in 8250.c
Quoted 8 lines · Alan Cox
Quoted 5 lines · On Thu, 31 Jul 2008 04:50:21 -0700 [email protected] (Eric W. Biederman)…
Quoted 4 lines
replace
[PATCH] serial: changeirq_liststo usedyn_array
use small array with index to handle irq locking for serial port hope 32 slot is enough
Quoted 4 lines
Quoted 2 lines
Could you size this array by
NR_UARTS(our worst case usage) and placeirq_noin structirq_info?
NR_UARTSis 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
Re: [PATCH] serial: change remove NR_IRQS in 8250.c
Quoted 8 lines
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
Re: [PATCH] serial: change remove NR_IRQS in 8250.c
In reply to Eric W. BiedermanQuoted 6 lines · Eric W. Biederman
Quoted 4 lines
replace
[PATCH] serial: changeirq_liststo usedyn_array
use small array with index to handle irq locking for serial port hope 32 slot is enoughCould you size this array by
NR_UARTS(our worst case usage)
how about crazy user set that too big?
Quoted 1 line
and place
irq_noin structirq_info?
should be ok
Quoted 4 lines
Also you want to hold
irq_info->lockwhen you set or clearirq_no. Just to be on the safe side. I expect we can avoid clearing theirq_noin theirq_listsand prevent a few more races from being a possibility.
will try
YH
PATCH 2/3 add per_cpu_dyn_array support
In reply to Yinghai Luso could make array in per_cpu is allocated dynamically too
--- 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(-)
arch/x86/kernel/setup_percpu.c +5 -2
@@ -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",
include/asm-generic/vmlinux.lds.h +6 -0
@@ -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) { \
include/linux/init.h +24 -3
@@ -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__ */ /**
init/main.c +57 -0
63 lines not on this page · raw message
PATCH 3/3 irq: make irqs in kernel stat use per_cpu_dyn_array
In reply to Yinghai Lu--- include/linux/kernel_stat.h | 4 ++++ kernel/sched.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-)
include/linux/kernel_stat.h +4 -0
@@ -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);
kernel/sched.c +4 -1
@@ -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.
PATCH 1/1 x86 remove irq_vectors_limit.h
In reply to Yinghai Luno 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
include/asm-x86/mach-generic/irq_vectors_limits.h deleted +0 -14
@@ -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 */
include/asm-x86/summit/irq_vectors_limits.h deleted +0 -14
@@ -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 */
Re: [PATCH 0/3] dyn_array support #2
In reply to Yinghai LuQuoted 5 lines · Yinghai Lu
please check the patches adding
dyn_arrayandnr_irqs#2Thanks
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
Re: [PATCH 0/3] dyn_array support #2
Quoted 17 lines · Mike Travis
Quoted 5 lines · Yinghai Lu
please check the patches adding
dyn_arrayandnr_irqs#2Thanks
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.
Quoted 3 lines
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...
Quoted 4 lines
Plus, I still like Ingo's suggestion to not change
NR_IRQS==>nr_irqs.CONFIG_ARCH_HAS_DYNAMIC_IRQSspells out exactly whatNR_IRQSmeans. (Even more accurate would beCONFIG_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.
Quoted 3 lines
The
DEFINE_DYN_ARRAYcould be the following. (Changing general purposeDYN_ARRAYto specifically purposedIRQ_ARRAY.)
dyn_array is some more generic, and nr_irqs is one of it's user
Quoted 9 lines
#ifdef
CONFIG_ARCH_HAS_DYNAMIC_IRQS
#defineDEFINE_IRQ_ARRAY<new variable irq array [or list] definition> #else
#defineDEFINE_IRQ_ARRAY<old static irq array>
#endifFor the immediate problem, unraveling the code merge back to IRQ's based on
NR_IOAPICSwould 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
Re: [PATCH 0/3] dyn_array support #2
In reply to Yinghai LuQuoted 1 line · Yinghai Lu
please check the patches adding
dyn_arrayandnr_irqs#2
Why can't we use a radix tree like powerpc does?
Re: [PATCH 0/3] dyn_array support #2
Quoted 5 lines · Peter Zijlstra
Quoted 1 line · Yinghai Lu
please check the patches adding
dyn_arrayandnr_irqs#2Why can't we use a radix tree like powerpc does?
which file in arch/power i could look?
YH
Re: [PATCH 0/3] dyn_array support #2
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
Re: [PATCH 0/3] dyn_array support #2
please check v2 , base to tip/master
1. address eric about irq_info changing
2. less print out
YH
Re: [PATCH 0/3] dyn_array support #2
In reply to Peter ZijlstraQuoted 4 lines · Peter Zijlstra
Quoted 1 line · Yinghai Lu
please check the patches adding
dyn_arrayandnr_irqs#2Why 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
Re: [PATCH 0/7] dyn_array support
In reply to Yinghai LuUgh. Looks like I forgot to hit send on this.
Quoted 1 line · Yinghai Lu
please check the patches adding
dyn_arrayandnr_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