* [PATCH 0/3] unify the allocation of irq vectors v2
@ 2008-09-19 20:02 Dean Nelson
2008-09-19 20:04 ` [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2 Dean Nelson
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Dean Nelson @ 2008-09-19 20:02 UTC (permalink / raw)
To: Ingo Molnar
Cc: Eric W. Biederman, H. Peter Anvin, Jack Steiner, Alan Mayer,
jeremy, rusty, suresh.b.siddha, torvalds, linux-kernel,
Thomas Gleixner, Yinghai Lu
This patchset makes it so that all irq vectors are allocated via one function.
On Fri, Sep 19, 2008 at 10:48:56AM +0200, Ingo Molnar wrote:
>
> Dean, just to make sure the useful bits are not lost now that the
> direction has been changed: could you please repost the patchset but
> without the driver API bits? It's still all a nice and useful
> generalization and cleanup of the x86 vector allocation code, and we can
> check it in -tip how well it works in practice.
Ingo, hopefully this patchset reflects what you're looking for. Feel free
to change it anyway you like.
Thanks,
Dean
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2
2008-09-19 20:02 [PATCH 0/3] unify the allocation of irq vectors v2 Dean Nelson
@ 2008-09-19 20:04 ` Dean Nelson
2008-09-19 20:24 ` Mike Travis
2008-09-19 20:40 ` Yinghai Lu
2008-09-19 20:06 ` [PATCH 2/3] switch static system vector allocation to use vector_irq[] v2 Dean Nelson
2008-09-19 20:08 ` [PATCH 3/3] switch non-standard SYSCALL_VECTOR allocation to use vector_irq v2 Dean Nelson
2 siblings, 2 replies; 11+ messages in thread
From: Dean Nelson @ 2008-09-19 20:04 UTC (permalink / raw)
To: Ingo Molnar
Cc: Eric W. Biederman, H. Peter Anvin, Jack Steiner, Alan Mayer,
jeremy, rusty, suresh.b.siddha, torvalds, linux-kernel,
Thomas Gleixner, Yinghai Lu
Change per_cpu variable vector_irq[] from holding an 'int' irq number to
holding a 'struct irq_desc' pointer.
Signed-off-by: Dean Nelson <dcn@sgi.com>
---
Note that this pre-allocates the irq_desc structure before we know whether
a vector will be successfully found. And should it not, the irq_desc structure
is left created with the irq still unallocated. Should someone in the future
attempt to allocate a vector with that same irq and succeed, they will get
the previously allocated irq_desc structure.
Also, I won't claim the changes to arch/x86/xen/irq.c were correctly done, and
I know they weren't tested.
arch/x86/kernel/io_apic.c | 32 ++++++++++++++++++--------------
arch/x86/kernel/irq_32.c | 14 ++++++--------
arch/x86/kernel/irq_64.c | 10 ++++------
arch/x86/kernel/irqinit_32.c | 29 +++++++++--------------------
arch/x86/kernel/irqinit_64.c | 29 +++++++++--------------------
arch/x86/kernel/vmiclock_32.c | 2 +-
arch/x86/xen/irq.c | 3 ++-
include/asm-x86/hw_irq.h | 2 +-
8 files changed, 50 insertions(+), 71 deletions(-)
Index: linux/arch/x86/kernel/io_apic.c
===================================================================
--- linux.orig/arch/x86/kernel/io_apic.c 2008-09-19 14:12:25.000000000 -0500
+++ linux/arch/x86/kernel/io_apic.c 2008-09-19 14:13:09.000000000 -0500
@@ -1226,6 +1226,7 @@ static int __assign_irq_vector(int irq,
unsigned int old_vector;
int cpu;
struct irq_cfg *cfg;
+ struct irq_desc *desc;
cfg = irq_cfg(irq);
@@ -1243,6 +1244,8 @@ static int __assign_irq_vector(int irq,
return 0;
}
+ desc = irq_to_desc_alloc(irq);
+
for_each_cpu_mask_nr(cpu, mask) {
cpumask_t domain, new_mask;
int new_cpu;
@@ -1270,7 +1273,7 @@ next:
goto next;
#endif
for_each_cpu_mask_nr(new_cpu, new_mask)
- if (per_cpu(vector_irq, new_cpu)[vector] != -1)
+ if (per_cpu(vector_irq, new_cpu)[vector] != NULL)
goto next;
/* Found one! */
current_vector = vector;
@@ -1280,7 +1283,7 @@ next:
cfg->old_domain = cfg->domain;
}
for_each_cpu_mask_nr(new_cpu, new_mask)
- per_cpu(vector_irq, new_cpu)[vector] = irq;
+ per_cpu(vector_irq, new_cpu)[vector] = desc;
cfg->vector = vector;
cfg->domain = domain;
return 0;
@@ -1311,7 +1314,7 @@ static void __clear_irq_vector(int irq)
vector = cfg->vector;
cpus_and(mask, cfg->domain, cpu_online_map);
for_each_cpu_mask_nr(cpu, mask)
- per_cpu(vector_irq, cpu)[vector] = -1;
+ per_cpu(vector_irq, cpu)[vector] = NULL;
cfg->vector = 0;
cpus_clear(cfg->domain);
@@ -1323,23 +1326,26 @@ void __setup_vector_irq(int cpu)
/* This function must be called with vector_lock held */
int irq, vector;
struct irq_cfg *cfg;
+ struct irq_desc *desc;
/* Mark the inuse vectors */
for_each_irq_cfg(irq, cfg) {
if (!cpu_isset(cpu, cfg->domain))
continue;
vector = cfg->vector;
- per_cpu(vector_irq, cpu)[vector] = irq;
+ desc = irq_to_desc(irq);
+ BUG_ON(desc == NULL);
+ per_cpu(vector_irq, cpu)[vector] = desc;
}
/* Mark the free vectors */
for (vector = 0; vector < NR_VECTORS; ++vector) {
- irq = per_cpu(vector_irq, cpu)[vector];
- if (irq < 0)
+ desc = per_cpu(vector_irq, cpu)[vector];
+ if (desc == NULL)
continue;
- cfg = irq_cfg(irq);
+ cfg = irq_cfg(desc->irq);
if (!cpu_isset(cpu, cfg->domain))
- per_cpu(vector_irq, cpu)[vector] = -1;
+ per_cpu(vector_irq, cpu)[vector] = NULL;
}
}
@@ -2389,16 +2395,14 @@ asmlinkage void smp_irq_move_cleanup_int
me = smp_processor_id();
for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
- unsigned int irq;
struct irq_desc *desc;
struct irq_cfg *cfg;
- irq = __get_cpu_var(vector_irq)[vector];
- desc = irq_to_desc(irq);
- if (!desc)
+ desc = __get_cpu_var(vector_irq)[vector];
+ if (desc == NULL)
continue;
- cfg = irq_cfg(irq);
+ cfg = irq_cfg(desc->irq);
spin_lock(&desc->lock);
if (!cfg->move_cleanup_count)
goto unlock;
@@ -2406,7 +2410,7 @@ asmlinkage void smp_irq_move_cleanup_int
if ((vector == cfg->vector) && cpu_isset(me, cfg->domain))
goto unlock;
- __get_cpu_var(vector_irq)[vector] = -1;
+ __get_cpu_var(vector_irq)[vector] = NULL;
cfg->move_cleanup_count--;
unlock:
spin_unlock(&desc->lock);
Index: linux/include/asm-x86/hw_irq.h
===================================================================
--- linux.orig/include/asm-x86/hw_irq.h 2008-09-19 14:12:25.000000000 -0500
+++ linux/include/asm-x86/hw_irq.h 2008-09-19 14:13:09.000000000 -0500
@@ -113,7 +113,7 @@ extern asmlinkage void smp_invalidate_in
extern void (*const interrupt[NR_VECTORS])(void);
#endif
-typedef int vector_irq_t[NR_VECTORS];
+typedef struct irq_desc *vector_irq_t[NR_VECTORS];
DECLARE_PER_CPU(vector_irq_t, vector_irq);
#ifdef CONFIG_X86_IO_APIC
Index: linux/arch/x86/kernel/irq_32.c
===================================================================
--- linux.orig/arch/x86/kernel/irq_32.c 2008-09-19 14:12:25.000000000 -0500
+++ linux/arch/x86/kernel/irq_32.c 2008-09-19 14:13:09.000000000 -0500
@@ -226,26 +226,24 @@ unsigned int do_IRQ(struct pt_regs *regs
int overflow;
unsigned vector = ~regs->orig_ax;
struct irq_desc *desc;
- unsigned irq;
old_regs = set_irq_regs(regs);
irq_enter();
- irq = __get_cpu_var(vector_irq)[vector];
overflow = check_stack_overflow();
- desc = irq_to_desc(irq);
- if (unlikely(!desc)) {
- printk(KERN_EMERG "%s: cannot handle IRQ %d vector %#x cpu %d\n",
- __func__, irq, vector, smp_processor_id());
+ desc = __get_cpu_var(vector_irq)[vector];
+ if (unlikely(desc == NULL)) {
+ printk(KERN_EMERG "%s: cannot handle IRQ vector %#x cpu %d\n",
+ __func__, vector, smp_processor_id());
BUG();
}
- if (!execute_on_irq_stack(overflow, desc, irq)) {
+ if (!execute_on_irq_stack(overflow, desc, desc->irq)) {
if (unlikely(overflow))
print_stack_overflow();
- desc->handle_irq(irq, desc);
+ desc->handle_irq(desc->irq, desc);
}
irq_exit();
Index: linux/arch/x86/kernel/irq_64.c
===================================================================
--- linux.orig/arch/x86/kernel/irq_64.c 2008-09-19 14:12:25.000000000 -0500
+++ linux/arch/x86/kernel/irq_64.c 2008-09-19 14:13:09.000000000 -0500
@@ -213,20 +213,18 @@ asmlinkage unsigned int do_IRQ(struct pt
/* high bit used in ret_from_ code */
unsigned vector = ~regs->orig_ax;
- unsigned irq;
exit_idle();
irq_enter();
- irq = __get_cpu_var(vector_irq)[vector];
#ifdef CONFIG_DEBUG_STACKOVERFLOW
stack_overflow_check(regs);
#endif
- desc = irq_to_desc(irq);
- if (likely(desc))
- generic_handle_irq_desc(irq, desc);
- else {
+ desc = __get_cpu_var(vector_irq)[vector];
+ if (likely(desc != NULL)) {
+ generic_handle_irq_desc(desc->irq, desc);
+ } else {
if (!disable_apic)
ack_APIC_irq();
Index: linux/arch/x86/kernel/vmiclock_32.c
===================================================================
--- linux.orig/arch/x86/kernel/vmiclock_32.c 2008-09-19 14:12:25.000000000 -0500
+++ linux/arch/x86/kernel/vmiclock_32.c 2008-09-19 14:13:09.000000000 -0500
@@ -242,7 +242,7 @@ void __init vmi_time_init(void)
vmi_time_init_clockevent();
setup_irq(0, &vmi_clock_action);
for_each_possible_cpu(cpu)
- per_cpu(vector_irq, cpu)[vmi_get_timer_vector()] = 0;
+ per_cpu(vector_irq, cpu)[vmi_get_timer_vector()] = NULL;
}
#ifdef CONFIG_X86_LOCAL_APIC
Index: linux/arch/x86/xen/irq.c
===================================================================
--- linux.orig/arch/x86/xen/irq.c 2008-09-19 14:12:25.000000000 -0500
+++ linux/arch/x86/xen/irq.c 2008-09-19 14:13:09.000000000 -0500
@@ -27,8 +27,9 @@ static void __init __xen_init_IRQ(void)
for(i = 0; i < NR_VECTORS; i++) {
int cpu;
+ desc = irq_to_desc_alloc(i);
for_each_possible_cpu(cpu)
- per_cpu(vector_irq, cpu)[i] = i;
+ per_cpu(vector_irq, cpu)[i] = desc;
}
xen_init_IRQ();
Index: linux/arch/x86/kernel/irqinit_32.c
===================================================================
--- linux.orig/arch/x86/kernel/irqinit_32.c 2008-09-19 14:12:25.000000000 -0500
+++ linux/arch/x86/kernel/irqinit_32.c 2008-09-19 14:13:09.000000000 -0500
@@ -59,6 +59,8 @@ static struct irqaction fpu_irq = {
void __init init_ISA_irqs (void)
{
int i;
+ int cpu;
+ unsigned int vector;
#ifdef CONFIG_X86_LOCAL_APIC
init_bsp_APIC();
@@ -76,6 +78,12 @@ void __init init_ISA_irqs (void)
desc->action = NULL;
desc->depth = 1;
+ vector = IRQ0_VECTOR + i;
+ for_each_possible_cpu(cpu) {
+ BUG_ON(per_cpu(vector_irq, cpu)[vector] != NULL);
+ per_cpu(vector_irq, cpu)[vector] = desc;
+ }
+
set_irq_chip_and_handler_name(i, &i8259A_chip,
handle_level_irq, "XT");
}
@@ -90,26 +98,7 @@ static struct irqaction irq2 = {
.name = "cascade",
};
-DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
- [0 ... IRQ0_VECTOR - 1] = -1,
- [IRQ0_VECTOR] = 0,
- [IRQ1_VECTOR] = 1,
- [IRQ2_VECTOR] = 2,
- [IRQ3_VECTOR] = 3,
- [IRQ4_VECTOR] = 4,
- [IRQ5_VECTOR] = 5,
- [IRQ6_VECTOR] = 6,
- [IRQ7_VECTOR] = 7,
- [IRQ8_VECTOR] = 8,
- [IRQ9_VECTOR] = 9,
- [IRQ10_VECTOR] = 10,
- [IRQ11_VECTOR] = 11,
- [IRQ12_VECTOR] = 12,
- [IRQ13_VECTOR] = 13,
- [IRQ14_VECTOR] = 14,
- [IRQ15_VECTOR] = 15,
- [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
-};
+DEFINE_PER_CPU(vector_irq_t, vector_irq);
/* Overridden in paravirt.c */
void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
Index: linux/arch/x86/kernel/irqinit_64.c
===================================================================
--- linux.orig/arch/x86/kernel/irqinit_64.c 2008-09-19 14:12:25.000000000 -0500
+++ linux/arch/x86/kernel/irqinit_64.c 2008-09-19 14:13:09.000000000 -0500
@@ -114,30 +114,13 @@ static struct irqaction irq2 = {
.mask = CPU_MASK_NONE,
.name = "cascade",
};
-DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
- [0 ... IRQ0_VECTOR - 1] = -1,
- [IRQ0_VECTOR] = 0,
- [IRQ1_VECTOR] = 1,
- [IRQ2_VECTOR] = 2,
- [IRQ3_VECTOR] = 3,
- [IRQ4_VECTOR] = 4,
- [IRQ5_VECTOR] = 5,
- [IRQ6_VECTOR] = 6,
- [IRQ7_VECTOR] = 7,
- [IRQ8_VECTOR] = 8,
- [IRQ9_VECTOR] = 9,
- [IRQ10_VECTOR] = 10,
- [IRQ11_VECTOR] = 11,
- [IRQ12_VECTOR] = 12,
- [IRQ13_VECTOR] = 13,
- [IRQ14_VECTOR] = 14,
- [IRQ15_VECTOR] = 15,
- [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
-};
+DEFINE_PER_CPU(vector_irq_t, vector_irq);
static void __init init_ISA_irqs (void)
{
int i;
+ int cpu;
+ unsigned int vector;
init_bsp_APIC();
init_8259A(0);
@@ -150,6 +133,12 @@ static void __init init_ISA_irqs (void)
desc->action = NULL;
desc->depth = 1;
+ vector = IRQ0_VECTOR + i;
+ for_each_possible_cpu(cpu) {
+ BUG_ON(per_cpu(vector_irq, cpu)[vector] != NULL);
+ per_cpu(vector_irq, cpu)[vector] = desc;
+ }
+
/*
* 16 old-style INTA-cycle interrupts:
*/
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/3] switch static system vector allocation to use vector_irq[] v2
2008-09-19 20:02 [PATCH 0/3] unify the allocation of irq vectors v2 Dean Nelson
2008-09-19 20:04 ` [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2 Dean Nelson
@ 2008-09-19 20:06 ` Dean Nelson
2008-09-19 20:08 ` [PATCH 3/3] switch non-standard SYSCALL_VECTOR allocation to use vector_irq v2 Dean Nelson
2 siblings, 0 replies; 11+ messages in thread
From: Dean Nelson @ 2008-09-19 20:06 UTC (permalink / raw)
To: Ingo Molnar
Cc: Eric W. Biederman, H. Peter Anvin, Jack Steiner, Alan Mayer,
jeremy, rusty, suresh.b.siddha, torvalds, linux-kernel,
Thomas Gleixner, Yinghai Lu
Replace the current use of system_vectors[] for the allocation of static
system vectors by also using the per_cpu variable vector_irq[].
Signed-off-by: Dean Nelson <dcn@sgi.com>
---
arch/x86/kernel/Makefile | 2
arch/x86/kernel/apic.c | 2
arch/x86/kernel/io_apic.c | 112 ++++++++++++++++++++-------------------
arch/x86/kernel/irq.c | 22 +++++++
arch/x86/kernel/irq_32.c | 2
arch/x86/kernel/irq_64.c | 2
arch/x86/kernel/irqinit_32.c | 11 ++-
arch/x86/kernel/irqinit_64.c | 11 ++-
include/asm-x86/desc.h | 21 +++----
include/asm-x86/hw_irq.h | 4 -
include/asm-x86/irq.h | 8 ++
11 files changed, 118 insertions(+), 79 deletions(-)
Index: linux/arch/x86/kernel/apic.c
===================================================================
--- linux.orig/arch/x86/kernel/apic.c 2008-09-19 14:12:25.000000000 -0500
+++ linux/arch/x86/kernel/apic.c 2008-09-19 14:13:17.000000000 -0500
@@ -118,8 +118,6 @@ EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok
int first_system_vector = 0xfe;
-char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};
-
/*
* Debug level, exported for io_apic.c
*/
Index: linux/include/asm-x86/desc.h
===================================================================
--- linux.orig/include/asm-x86/desc.h 2008-09-19 14:12:25.000000000 -0500
+++ linux/include/asm-x86/desc.h 2008-09-19 14:13:17.000000000 -0500
@@ -5,6 +5,7 @@
#include <asm/desc_defs.h>
#include <asm/ldt.h>
#include <asm/mmu.h>
+#include <asm/irq.h>
#include <linux/smp.h>
static inline void fill_ldt(struct desc_struct *desc,
@@ -320,20 +321,20 @@ static inline void set_intr_gate(unsigne
_set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
}
-#define SYS_VECTOR_FREE 0
-#define SYS_VECTOR_ALLOCED 1
-
extern int first_system_vector;
-extern char system_vectors[];
static inline void alloc_system_vector(int vector)
{
- if (system_vectors[vector] == SYS_VECTOR_FREE) {
- system_vectors[vector] = SYS_VECTOR_ALLOCED;
- if (first_system_vector > vector)
- first_system_vector = vector;
- } else
- BUG();
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&vector_lock, flags);
+ ret = grab_irq_vector(NON_IRQ_DESC, vector, &cpu_possible_map);
+ BUG_ON(ret != vector);
+
+ if (first_system_vector > vector)
+ first_system_vector = vector;
+ spin_unlock_irqrestore(&vector_lock, flags);
}
static inline void alloc_intr_gate(unsigned int n, void *addr)
Index: linux/arch/x86/kernel/io_apic.c
===================================================================
--- linux.orig/arch/x86/kernel/io_apic.c 2008-09-19 14:13:09.000000000 -0500
+++ linux/arch/x86/kernel/io_apic.c 2008-09-19 14:13:17.000000000 -0500
@@ -72,7 +72,6 @@
int sis_apic_bug = -1;
static DEFINE_SPINLOCK(ioapic_lock);
-static DEFINE_SPINLOCK(vector_lock);
/*
* # of IRQ routing registers
@@ -546,7 +545,7 @@ static void __target_IO_APIC_irq(unsigne
}
}
-static int assign_irq_vector(int irq, cpumask_t mask);
+static int assign_irq_vector(int irq, cpumask_t *mask);
static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
{
@@ -561,7 +560,7 @@ static void set_ioapic_affinity_irq(unsi
return;
cfg = irq_cfg(irq);
- if (assign_irq_vector(irq, mask))
+ if (assign_irq_vector(irq, &mask))
return;
cpus_and(tmp, cfg->domain, mask);
@@ -1196,20 +1195,33 @@ static int pin_2_irq(int idx, int apic,
return irq;
}
-void lock_vector_lock(void)
+static int ioapic_grab_irq_vector(struct irq_desc *desc, unsigned int vector,
+ cpumask_t *domain, cpumask_t *domain_online)
{
- /* Used to the online set of cpus does not change
- * during assign_irq_vector.
- */
- spin_lock(&vector_lock);
-}
+ struct irq_cfg *cfg;
+ int ret;
-void unlock_vector_lock(void)
-{
- spin_unlock(&vector_lock);
+ BUG_ON(!spin_is_locked(&vector_lock));
+
+ ret = grab_irq_vector(desc, vector, domain_online);
+ if (ret == vector) {
+ cfg = irq_cfg(desc->irq);
+ if (cfg->vector) {
+ cfg->move_in_progress = 1;
+ cfg->old_domain = cfg->domain;
+ }
+ cfg->vector = vector;
+ cfg->domain = *domain;
+ }
+ return ret;
}
-static int __assign_irq_vector(int irq, cpumask_t mask)
+/* The following scratch cpumask_t variables are protected by vector lock. */
+static cpumask_t eligible_cpus;
+static cpumask_t domain;
+static cpumask_t domain_online;
+
+static int __assign_irq_vector(int irq, cpumask_t *mask)
{
/*
* NOTE! The local APIC isn't very good at handling
@@ -1223,36 +1235,34 @@ static int __assign_irq_vector(int irq,
* 0x80, because int 0x80 is hm, kind of importantish. ;)
*/
static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
- unsigned int old_vector;
int cpu;
struct irq_cfg *cfg;
struct irq_desc *desc;
+ int ret;
- cfg = irq_cfg(irq);
+ BUG_ON(!spin_is_locked(&vector_lock));
- /* Only try and allocate irqs on cpus that are present */
- cpus_and(mask, mask, cpu_online_map);
+ cfg = irq_cfg(irq);
if ((cfg->move_in_progress) || cfg->move_cleanup_count)
return -EBUSY;
- old_vector = cfg->vector;
- if (old_vector) {
- cpumask_t tmp;
- cpus_and(tmp, cfg->domain, mask);
- if (!cpus_empty(tmp))
+ /* Only try and allocate irqs on cpus that are present */
+ cpus_and(eligible_cpus, *mask, cpu_online_map);
+
+ if (cfg->vector) {
+ cpus_and(domain, cfg->domain, eligible_cpus);
+ if (!cpus_empty(domain))
return 0;
}
desc = irq_to_desc_alloc(irq);
- for_each_cpu_mask_nr(cpu, mask) {
- cpumask_t domain, new_mask;
- int new_cpu;
+ for_each_cpu_mask_nr(cpu, eligible_cpus) {
int vector, offset;
domain = vector_allocation_domain(cpu);
- cpus_and(new_mask, domain, cpu_online_map);
+ cpus_and(domain_online, domain, cpu_online_map);
vector = current_vector;
offset = current_offset;
@@ -1272,26 +1282,20 @@ next:
if (vector == SYSCALL_VECTOR)
goto next;
#endif
- for_each_cpu_mask_nr(new_cpu, new_mask)
- if (per_cpu(vector_irq, new_cpu)[vector] != NULL)
- goto next;
+ ret = ioapic_grab_irq_vector(desc, vector, &domain,
+ &domain_online);
+ if (ret != vector)
+ goto next;
+
/* Found one! */
current_vector = vector;
current_offset = offset;
- if (old_vector) {
- cfg->move_in_progress = 1;
- cfg->old_domain = cfg->domain;
- }
- for_each_cpu_mask_nr(new_cpu, new_mask)
- per_cpu(vector_irq, new_cpu)[vector] = desc;
- cfg->vector = vector;
- cfg->domain = domain;
return 0;
}
return -ENOSPC;
}
-static int assign_irq_vector(int irq, cpumask_t mask)
+static int assign_irq_vector(int irq, cpumask_t *mask)
{
int err;
unsigned long flags;
@@ -1334,13 +1338,13 @@ void __setup_vector_irq(int cpu)
continue;
vector = cfg->vector;
desc = irq_to_desc(irq);
- BUG_ON(desc == NULL);
+ BUG_ON(desc == NULL || desc == NON_IRQ_DESC);
per_cpu(vector_irq, cpu)[vector] = desc;
}
/* Mark the free vectors */
for (vector = 0; vector < NR_VECTORS; ++vector) {
desc = per_cpu(vector_irq, cpu)[vector];
- if (desc == NULL)
+ if (desc == NULL || desc == NON_IRQ_DESC)
continue;
cfg = irq_cfg(desc->irq);
@@ -1495,7 +1499,7 @@ static void setup_IO_APIC_irq(int apic,
cfg = irq_cfg(irq);
mask = TARGET_CPUS;
- if (assign_irq_vector(irq, mask))
+ if (assign_irq_vector(irq, &mask))
return;
cpus_and(mask, cfg->domain, mask);
@@ -2280,7 +2284,7 @@ static void migrate_ioapic_irq(int irq,
if (get_irte(irq, &irte))
return;
- if (assign_irq_vector(irq, mask))
+ if (assign_irq_vector(irq, &mask))
return;
cfg = irq_cfg(irq);
@@ -2399,7 +2403,7 @@ asmlinkage void smp_irq_move_cleanup_int
struct irq_cfg *cfg;
desc = __get_cpu_var(vector_irq)[vector];
- if (desc == NULL)
+ if (desc == NULL || desc == NON_IRQ_DESC)
continue;
cfg = irq_cfg(desc->irq);
@@ -2764,6 +2768,7 @@ static inline void __init check_timer(vo
unsigned long flags;
unsigned int ver;
int no_pin1 = 0;
+ cpumask_t mask;
local_irq_save(flags);
@@ -2774,7 +2779,8 @@ static inline void __init check_timer(vo
* get/set the timer IRQ vector:
*/
disable_8259A_irq(0);
- assign_irq_vector(0, TARGET_CPUS);
+ mask = TARGET_CPUS;
+ assign_irq_vector(0, &mask);
/*
* As IRQ0 is to be enabled in the 8259A, the virtual
@@ -3074,10 +3080,12 @@ unsigned int create_irq_nr(unsigned int
unsigned int new;
unsigned long flags;
struct irq_cfg *cfg_new;
+ cpumask_t mask;
#ifndef CONFIG_HAVE_SPARSE_IRQ
irq_want = nr_irqs - 1;
#endif
+ mask = TARGET_CPUS;
irq = 0;
spin_lock_irqsave(&vector_lock, flags);
@@ -3090,7 +3098,7 @@ unsigned int create_irq_nr(unsigned int
/* check if need to create one */
if (!cfg_new)
cfg_new = irq_cfg_alloc(new);
- if (__assign_irq_vector(new, TARGET_CPUS) == 0)
+ if (__assign_irq_vector(new, &mask) == 0)
irq = new;
break;
}
@@ -3140,7 +3148,7 @@ static int msi_compose_msg(struct pci_de
cpumask_t tmp;
tmp = TARGET_CPUS;
- err = assign_irq_vector(irq, tmp);
+ err = assign_irq_vector(irq, &tmp);
if (err)
return err;
@@ -3212,7 +3220,7 @@ static void set_msi_irq_affinity(unsigne
if (cpus_empty(tmp))
return;
- if (assign_irq_vector(irq, mask))
+ if (assign_irq_vector(irq, &mask))
return;
cfg = irq_cfg(irq);
@@ -3251,7 +3259,7 @@ static void ir_set_msi_irq_affinity(unsi
if (get_irte(irq, &irte))
return;
- if (assign_irq_vector(irq, mask))
+ if (assign_irq_vector(irq, &mask))
return;
cfg = irq_cfg(irq);
@@ -3491,7 +3499,7 @@ static void dmar_msi_set_affinity(unsign
if (cpus_empty(tmp))
return;
- if (assign_irq_vector(irq, mask))
+ if (assign_irq_vector(irq, &mask))
return;
cfg = irq_cfg(irq);
@@ -3552,7 +3560,7 @@ static void hpet_msi_set_affinity(unsign
if (cpus_empty(tmp))
return;
- if (assign_irq_vector(irq, mask))
+ if (assign_irq_vector(irq, &mask))
return;
cfg = irq_cfg(irq);
@@ -3632,7 +3640,7 @@ static void set_ht_irq_affinity(unsigned
if (cpus_empty(tmp))
return;
- if (assign_irq_vector(irq, mask))
+ if (assign_irq_vector(irq, &mask))
return;
cfg = irq_cfg(irq);
@@ -3663,7 +3671,7 @@ int arch_setup_ht_irq(unsigned int irq,
cpumask_t tmp;
tmp = TARGET_CPUS;
- err = assign_irq_vector(irq, tmp);
+ err = assign_irq_vector(irq, &tmp);
if (!err) {
struct ht_irq_msg msg;
unsigned dest;
Index: linux/arch/x86/kernel/irq_32.c
===================================================================
--- linux.orig/arch/x86/kernel/irq_32.c 2008-09-19 14:13:09.000000000 -0500
+++ linux/arch/x86/kernel/irq_32.c 2008-09-19 14:13:17.000000000 -0500
@@ -234,7 +234,7 @@ unsigned int do_IRQ(struct pt_regs *regs
overflow = check_stack_overflow();
desc = __get_cpu_var(vector_irq)[vector];
- if (unlikely(desc == NULL)) {
+ if (unlikely(desc == NULL || desc == NON_IRQ_DESC)) {
printk(KERN_EMERG "%s: cannot handle IRQ vector %#x cpu %d\n",
__func__, vector, smp_processor_id());
BUG();
Index: linux/arch/x86/kernel/irq_64.c
===================================================================
--- linux.orig/arch/x86/kernel/irq_64.c 2008-09-19 14:13:09.000000000 -0500
+++ linux/arch/x86/kernel/irq_64.c 2008-09-19 14:13:17.000000000 -0500
@@ -222,7 +222,7 @@ asmlinkage unsigned int do_IRQ(struct pt
#endif
desc = __get_cpu_var(vector_irq)[vector];
- if (likely(desc != NULL)) {
+ if (likely(desc != NULL && desc != NON_IRQ_DESC)) {
generic_handle_irq_desc(desc->irq, desc);
} else {
if (!disable_apic)
Index: linux/include/asm-x86/irq.h
===================================================================
--- linux.orig/include/asm-x86/irq.h 2008-09-19 14:12:25.000000000 -0500
+++ linux/include/asm-x86/irq.h 2008-09-19 14:13:17.000000000 -0500
@@ -47,4 +47,12 @@ extern void native_init_IRQ(void);
/* Interrupt vector management */
extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
+struct irq_desc;
+extern int grab_irq_vector(struct irq_desc *desc, unsigned int vector,
+ cpumask_t *new_domain_mask);
+
+#define NON_IRQ_DESC ((struct irq_desc *)-1UL)
+
+extern spinlock_t vector_lock;
+
#endif /* ASM_X86__IRQ_H */
Index: linux/arch/x86/kernel/Makefile
===================================================================
--- linux.orig/arch/x86/kernel/Makefile 2008-09-19 14:12:25.000000000 -0500
+++ linux/arch/x86/kernel/Makefile 2008-09-19 14:13:17.000000000 -0500
@@ -24,7 +24,7 @@ CFLAGS_tsc.o := $(nostackp)
CFLAGS_paravirt.o := $(nostackp)
obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
-obj-y += traps_$(BITS).o irq_$(BITS).o
+obj-y += traps_$(BITS).o irq.o irq_$(BITS).o
obj-y += time_$(BITS).o ioport.o ldt.o
obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o
obj-$(CONFIG_X86_VISWS) += visws_quirks.o
Index: linux/arch/x86/kernel/irq.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/x86/kernel/irq.c 2008-09-19 14:13:17.000000000 -0500
@@ -0,0 +1,22 @@
+#include <linux/irq.h>
+
+DEFINE_SPINLOCK(vector_lock);
+
+int grab_irq_vector(struct irq_desc *desc, unsigned int vector,
+ cpumask_t *domain)
+{
+ int cpu;
+
+ BUG_ON(!spin_is_locked(&vector_lock));
+
+ for_each_cpu_mask_nr(cpu, *domain) {
+ if (per_cpu(vector_irq, cpu)[vector] != NULL)
+ return -EBUSY;
+ }
+
+ /* it's available, reserve it */
+ for_each_cpu_mask_nr(cpu, *domain)
+ per_cpu(vector_irq, cpu)[vector] = desc;
+
+ return vector;
+}
Index: linux/include/asm-x86/hw_irq.h
===================================================================
--- linux.orig/include/asm-x86/hw_irq.h 2008-09-19 14:13:09.000000000 -0500
+++ linux/include/asm-x86/hw_irq.h 2008-09-19 14:13:17.000000000 -0500
@@ -117,8 +117,8 @@ typedef struct irq_desc *vector_irq_t[NR
DECLARE_PER_CPU(vector_irq_t, vector_irq);
#ifdef CONFIG_X86_IO_APIC
-extern void lock_vector_lock(void);
-extern void unlock_vector_lock(void);
+static inline void lock_vector_lock(void) { spin_lock(&vector_lock); }
+static inline void unlock_vector_lock(void) { spin_unlock(&vector_lock); }
extern void __setup_vector_irq(int cpu);
#else
static inline void lock_vector_lock(void) {}
Index: linux/arch/x86/kernel/irqinit_32.c
===================================================================
--- linux.orig/arch/x86/kernel/irqinit_32.c 2008-09-19 14:13:09.000000000 -0500
+++ linux/arch/x86/kernel/irqinit_32.c 2008-09-19 14:13:17.000000000 -0500
@@ -59,8 +59,9 @@ static struct irqaction fpu_irq = {
void __init init_ISA_irqs (void)
{
int i;
- int cpu;
+ int ret;
unsigned int vector;
+ unsigned long flags;
#ifdef CONFIG_X86_LOCAL_APIC
init_bsp_APIC();
@@ -79,10 +80,10 @@ void __init init_ISA_irqs (void)
desc->depth = 1;
vector = IRQ0_VECTOR + i;
- for_each_possible_cpu(cpu) {
- BUG_ON(per_cpu(vector_irq, cpu)[vector] != NULL);
- per_cpu(vector_irq, cpu)[vector] = desc;
- }
+ spin_lock_irqsave(&vector_lock, flags);
+ ret = grab_irq_vector(desc, vector, &cpu_possible_map);
+ BUG_ON(ret != vector);
+ spin_unlock_irqrestore(&vector_lock, flags);
set_irq_chip_and_handler_name(i, &i8259A_chip,
handle_level_irq, "XT");
Index: linux/arch/x86/kernel/irqinit_64.c
===================================================================
--- linux.orig/arch/x86/kernel/irqinit_64.c 2008-09-19 14:13:09.000000000 -0500
+++ linux/arch/x86/kernel/irqinit_64.c 2008-09-19 14:13:17.000000000 -0500
@@ -119,8 +119,9 @@ DEFINE_PER_CPU(vector_irq_t, vector_irq)
static void __init init_ISA_irqs (void)
{
int i;
- int cpu;
+ int ret;
unsigned int vector;
+ unsigned long flags;
init_bsp_APIC();
init_8259A(0);
@@ -134,10 +135,10 @@ static void __init init_ISA_irqs (void)
desc->depth = 1;
vector = IRQ0_VECTOR + i;
- for_each_possible_cpu(cpu) {
- BUG_ON(per_cpu(vector_irq, cpu)[vector] != NULL);
- per_cpu(vector_irq, cpu)[vector] = desc;
- }
+ spin_lock_irqsave(&vector_lock, flags);
+ ret = grab_irq_vector(desc, vector, &cpu_possible_map);
+ BUG_ON(ret != vector);
+ spin_unlock_irqrestore(&vector_lock, flags);
/*
* 16 old-style INTA-cycle interrupts:
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/3] switch non-standard SYSCALL_VECTOR allocation to use vector_irq v2
2008-09-19 20:02 [PATCH 0/3] unify the allocation of irq vectors v2 Dean Nelson
2008-09-19 20:04 ` [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2 Dean Nelson
2008-09-19 20:06 ` [PATCH 2/3] switch static system vector allocation to use vector_irq[] v2 Dean Nelson
@ 2008-09-19 20:08 ` Dean Nelson
2 siblings, 0 replies; 11+ messages in thread
From: Dean Nelson @ 2008-09-19 20:08 UTC (permalink / raw)
To: Ingo Molnar
Cc: Eric W. Biederman, H. Peter Anvin, Jack Steiner, Alan Mayer,
jeremy, rusty, suresh.b.siddha, torvalds, linux-kernel,
Thomas Gleixner, Yinghai Lu
Replace the current use of used_vectors[] for the allocation of a non-standard
SYSCALL_VECTOR by also using the per_cpu variable vector_irq[].
Signed-off-by: Dean Nelson <dcn@sgi.com>
---
arch/x86/kernel/traps_32.c | 16 ++++++++++------
drivers/lguest/interrupts_and_traps.c | 28 ++++++++++++++++++++++------
include/asm-x86/irq.h | 3 ---
3 files changed, 32 insertions(+), 15 deletions(-)
Index: linux/arch/x86/kernel/traps_32.c
===================================================================
--- linux.orig/arch/x86/kernel/traps_32.c 2008-09-19 11:01:10.000000000 -0500
+++ linux/arch/x86/kernel/traps_32.c 2008-09-19 12:35:32.000000000 -0500
@@ -63,9 +63,6 @@
#include "mach_traps.h"
-DECLARE_BITMAP(used_vectors, NR_VECTORS);
-EXPORT_SYMBOL_GPL(used_vectors);
-
asmlinkage int system_call(void);
/* Do we ignore FPU interrupts ? */
@@ -1185,6 +1182,8 @@ asmlinkage void math_emulate(long arg)
void __init trap_init(void)
{
int i;
+ int ret;
+ unsigned long flags;
#ifdef CONFIG_EISA
void __iomem *p = early_ioremap(0x0FFFD9, 4);
@@ -1232,10 +1231,15 @@ void __init trap_init(void)
set_system_gate(SYSCALL_VECTOR, &system_call);
/* Reserve all the builtin and the syscall vector: */
- for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
- set_bit(i, used_vectors);
+ spin_lock_irqsave(&vector_lock, flags);
+ for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) {
+ ret = grab_irq_vector(NON_IRQ_DESC, i, &cpu_possible_map);
+ BUG_ON(ret != i);
+ }
- set_bit(SYSCALL_VECTOR, used_vectors);
+ ret = grab_irq_vector(NON_IRQ_DESC, SYSCALL_VECTOR, &cpu_possible_map);
+ BUG_ON(ret != SYSCALL_VECTOR);
+ spin_unlock_irqrestore(&vector_lock, flags);
/*
* Should be a barrier for any external CPU state:
Index: linux/include/asm-x86/irq.h
===================================================================
--- linux.orig/include/asm-x86/irq.h 2008-09-19 11:09:32.000000000 -0500
+++ linux/include/asm-x86/irq.h 2008-09-19 12:35:32.000000000 -0500
@@ -44,9 +44,6 @@ extern unsigned int do_IRQ(struct pt_reg
extern void init_IRQ(void);
extern void native_init_IRQ(void);
-/* Interrupt vector management */
-extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
-
struct irq_desc;
extern int grab_irq_vector(struct irq_desc *desc, unsigned int vector,
cpumask_t *new_domain_mask);
Index: linux/drivers/lguest/interrupts_and_traps.c
===================================================================
--- linux.orig/drivers/lguest/interrupts_and_traps.c 2008-09-19 11:01:10.000000000 -0500
+++ linux/drivers/lguest/interrupts_and_traps.c 2008-09-19 12:41:02.000000000 -0500
@@ -221,19 +221,35 @@ bool check_syscall_vector(struct lguest
int init_interrupts(void)
{
+ unsigned long flags;
+ int ret;
+
/* If they want some strange system call vector, reserve it now */
- if (syscall_vector != SYSCALL_VECTOR
- && test_and_set_bit(syscall_vector, used_vectors)) {
- printk("lg: couldn't reserve syscall %u\n", syscall_vector);
- return -EBUSY;
+ if (syscall_vector != SYSCALL_VECTOR) {
+ spin_lock_irqsave(&vector_lock, flags);
+ ret = grab_irq_vector(NON_IRQ_DESC, syscall_vector,
+ &cpu_possible_map);
+ spin_unlock_irqrestore(&vector_lock, flags);
+ if (ret != syscall_vector) {
+ printk(KERN_WARNING "lg: couldn't reserve syscall %u\n",
+ syscall_vector);
+ return ret;
+ }
}
return 0;
}
void free_interrupts(void)
{
- if (syscall_vector != SYSCALL_VECTOR)
- clear_bit(syscall_vector, used_vectors);
+ int cpu;
+
+ if (syscall_vector != SYSCALL_VECTOR) {
+ for_each_possible_cpu(cpu) {
+ BUG_ON(per_cpu(vector_irq, cpu)[syscall_vector] !=
+ NON_IRQ_DESC);
+ per_cpu(vector_irq, cpu)[syscall_vector] = NULL;
+ }
+ }
}
/*H:220 Now we've got the routines to deliver interrupts, delivering traps like
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2
2008-09-19 20:04 ` [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2 Dean Nelson
@ 2008-09-19 20:24 ` Mike Travis
2008-09-19 23:17 ` Dean Nelson
2008-09-22 11:05 ` Ingo Molnar
2008-09-19 20:40 ` Yinghai Lu
1 sibling, 2 replies; 11+ messages in thread
From: Mike Travis @ 2008-09-19 20:24 UTC (permalink / raw)
To: Dean Nelson
Cc: Ingo Molnar, Eric W. Biederman, H. Peter Anvin, Jack Steiner,
Alan Mayer, jeremy, rusty, suresh.b.siddha, torvalds,
linux-kernel, Thomas Gleixner, Yinghai Lu
Hi Ingo,
Note that my recent patch from a couple of weeks ago, stripped almost all of
the cpumask_t's from the io_apic functions. Any chance we can apply them
before we add more?
I'd be willing to merge in Dean's patch over the top of mine (or vice-versa).
Thanks,
Mike
Dean Nelson wrote:
> Change per_cpu variable vector_irq[] from holding an 'int' irq number to
> holding a 'struct irq_desc' pointer.
>
> Signed-off-by: Dean Nelson <dcn@sgi.com>
>
> ---
>
> Note that this pre-allocates the irq_desc structure before we know whether
> a vector will be successfully found. And should it not, the irq_desc structure
> is left created with the irq still unallocated. Should someone in the future
> attempt to allocate a vector with that same irq and succeed, they will get
> the previously allocated irq_desc structure.
>
> Also, I won't claim the changes to arch/x86/xen/irq.c were correctly done, and
> I know they weren't tested.
>
> arch/x86/kernel/io_apic.c | 32 ++++++++++++++++++--------------
> arch/x86/kernel/irq_32.c | 14 ++++++--------
> arch/x86/kernel/irq_64.c | 10 ++++------
> arch/x86/kernel/irqinit_32.c | 29 +++++++++--------------------
> arch/x86/kernel/irqinit_64.c | 29 +++++++++--------------------
> arch/x86/kernel/vmiclock_32.c | 2 +-
> arch/x86/xen/irq.c | 3 ++-
> include/asm-x86/hw_irq.h | 2 +-
> 8 files changed, 50 insertions(+), 71 deletions(-)
>
> Index: linux/arch/x86/kernel/io_apic.c
> ===================================================================
> --- linux.orig/arch/x86/kernel/io_apic.c 2008-09-19 14:12:25.000000000 -0500
> +++ linux/arch/x86/kernel/io_apic.c 2008-09-19 14:13:09.000000000 -0500
> @@ -1226,6 +1226,7 @@ static int __assign_irq_vector(int irq,
> unsigned int old_vector;
> int cpu;
> struct irq_cfg *cfg;
> + struct irq_desc *desc;
>
> cfg = irq_cfg(irq);
>
> @@ -1243,6 +1244,8 @@ static int __assign_irq_vector(int irq,
> return 0;
> }
>
> + desc = irq_to_desc_alloc(irq);
> +
> for_each_cpu_mask_nr(cpu, mask) {
> cpumask_t domain, new_mask;
> int new_cpu;
> @@ -1270,7 +1273,7 @@ next:
> goto next;
> #endif
> for_each_cpu_mask_nr(new_cpu, new_mask)
> - if (per_cpu(vector_irq, new_cpu)[vector] != -1)
> + if (per_cpu(vector_irq, new_cpu)[vector] != NULL)
> goto next;
> /* Found one! */
> current_vector = vector;
> @@ -1280,7 +1283,7 @@ next:
> cfg->old_domain = cfg->domain;
> }
> for_each_cpu_mask_nr(new_cpu, new_mask)
> - per_cpu(vector_irq, new_cpu)[vector] = irq;
> + per_cpu(vector_irq, new_cpu)[vector] = desc;
> cfg->vector = vector;
> cfg->domain = domain;
> return 0;
> @@ -1311,7 +1314,7 @@ static void __clear_irq_vector(int irq)
> vector = cfg->vector;
> cpus_and(mask, cfg->domain, cpu_online_map);
> for_each_cpu_mask_nr(cpu, mask)
> - per_cpu(vector_irq, cpu)[vector] = -1;
> + per_cpu(vector_irq, cpu)[vector] = NULL;
>
> cfg->vector = 0;
> cpus_clear(cfg->domain);
> @@ -1323,23 +1326,26 @@ void __setup_vector_irq(int cpu)
> /* This function must be called with vector_lock held */
> int irq, vector;
> struct irq_cfg *cfg;
> + struct irq_desc *desc;
>
> /* Mark the inuse vectors */
> for_each_irq_cfg(irq, cfg) {
> if (!cpu_isset(cpu, cfg->domain))
> continue;
> vector = cfg->vector;
> - per_cpu(vector_irq, cpu)[vector] = irq;
> + desc = irq_to_desc(irq);
> + BUG_ON(desc == NULL);
> + per_cpu(vector_irq, cpu)[vector] = desc;
> }
> /* Mark the free vectors */
> for (vector = 0; vector < NR_VECTORS; ++vector) {
> - irq = per_cpu(vector_irq, cpu)[vector];
> - if (irq < 0)
> + desc = per_cpu(vector_irq, cpu)[vector];
> + if (desc == NULL)
> continue;
>
> - cfg = irq_cfg(irq);
> + cfg = irq_cfg(desc->irq);
> if (!cpu_isset(cpu, cfg->domain))
> - per_cpu(vector_irq, cpu)[vector] = -1;
> + per_cpu(vector_irq, cpu)[vector] = NULL;
> }
> }
>
> @@ -2389,16 +2395,14 @@ asmlinkage void smp_irq_move_cleanup_int
>
> me = smp_processor_id();
> for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
> - unsigned int irq;
> struct irq_desc *desc;
> struct irq_cfg *cfg;
> - irq = __get_cpu_var(vector_irq)[vector];
>
> - desc = irq_to_desc(irq);
> - if (!desc)
> + desc = __get_cpu_var(vector_irq)[vector];
> + if (desc == NULL)
> continue;
>
> - cfg = irq_cfg(irq);
> + cfg = irq_cfg(desc->irq);
> spin_lock(&desc->lock);
> if (!cfg->move_cleanup_count)
> goto unlock;
> @@ -2406,7 +2410,7 @@ asmlinkage void smp_irq_move_cleanup_int
> if ((vector == cfg->vector) && cpu_isset(me, cfg->domain))
> goto unlock;
>
> - __get_cpu_var(vector_irq)[vector] = -1;
> + __get_cpu_var(vector_irq)[vector] = NULL;
> cfg->move_cleanup_count--;
> unlock:
> spin_unlock(&desc->lock);
> Index: linux/include/asm-x86/hw_irq.h
> ===================================================================
> --- linux.orig/include/asm-x86/hw_irq.h 2008-09-19 14:12:25.000000000 -0500
> +++ linux/include/asm-x86/hw_irq.h 2008-09-19 14:13:09.000000000 -0500
> @@ -113,7 +113,7 @@ extern asmlinkage void smp_invalidate_in
> extern void (*const interrupt[NR_VECTORS])(void);
> #endif
>
> -typedef int vector_irq_t[NR_VECTORS];
> +typedef struct irq_desc *vector_irq_t[NR_VECTORS];
> DECLARE_PER_CPU(vector_irq_t, vector_irq);
>
> #ifdef CONFIG_X86_IO_APIC
> Index: linux/arch/x86/kernel/irq_32.c
> ===================================================================
> --- linux.orig/arch/x86/kernel/irq_32.c 2008-09-19 14:12:25.000000000 -0500
> +++ linux/arch/x86/kernel/irq_32.c 2008-09-19 14:13:09.000000000 -0500
> @@ -226,26 +226,24 @@ unsigned int do_IRQ(struct pt_regs *regs
> int overflow;
> unsigned vector = ~regs->orig_ax;
> struct irq_desc *desc;
> - unsigned irq;
>
>
> old_regs = set_irq_regs(regs);
> irq_enter();
> - irq = __get_cpu_var(vector_irq)[vector];
>
> overflow = check_stack_overflow();
>
> - desc = irq_to_desc(irq);
> - if (unlikely(!desc)) {
> - printk(KERN_EMERG "%s: cannot handle IRQ %d vector %#x cpu %d\n",
> - __func__, irq, vector, smp_processor_id());
> + desc = __get_cpu_var(vector_irq)[vector];
> + if (unlikely(desc == NULL)) {
> + printk(KERN_EMERG "%s: cannot handle IRQ vector %#x cpu %d\n",
> + __func__, vector, smp_processor_id());
> BUG();
> }
>
> - if (!execute_on_irq_stack(overflow, desc, irq)) {
> + if (!execute_on_irq_stack(overflow, desc, desc->irq)) {
> if (unlikely(overflow))
> print_stack_overflow();
> - desc->handle_irq(irq, desc);
> + desc->handle_irq(desc->irq, desc);
> }
>
> irq_exit();
> Index: linux/arch/x86/kernel/irq_64.c
> ===================================================================
> --- linux.orig/arch/x86/kernel/irq_64.c 2008-09-19 14:12:25.000000000 -0500
> +++ linux/arch/x86/kernel/irq_64.c 2008-09-19 14:13:09.000000000 -0500
> @@ -213,20 +213,18 @@ asmlinkage unsigned int do_IRQ(struct pt
>
> /* high bit used in ret_from_ code */
> unsigned vector = ~regs->orig_ax;
> - unsigned irq;
>
> exit_idle();
> irq_enter();
> - irq = __get_cpu_var(vector_irq)[vector];
>
> #ifdef CONFIG_DEBUG_STACKOVERFLOW
> stack_overflow_check(regs);
> #endif
>
> - desc = irq_to_desc(irq);
> - if (likely(desc))
> - generic_handle_irq_desc(irq, desc);
> - else {
> + desc = __get_cpu_var(vector_irq)[vector];
> + if (likely(desc != NULL)) {
> + generic_handle_irq_desc(desc->irq, desc);
> + } else {
> if (!disable_apic)
> ack_APIC_irq();
>
> Index: linux/arch/x86/kernel/vmiclock_32.c
> ===================================================================
> --- linux.orig/arch/x86/kernel/vmiclock_32.c 2008-09-19 14:12:25.000000000 -0500
> +++ linux/arch/x86/kernel/vmiclock_32.c 2008-09-19 14:13:09.000000000 -0500
> @@ -242,7 +242,7 @@ void __init vmi_time_init(void)
> vmi_time_init_clockevent();
> setup_irq(0, &vmi_clock_action);
> for_each_possible_cpu(cpu)
> - per_cpu(vector_irq, cpu)[vmi_get_timer_vector()] = 0;
> + per_cpu(vector_irq, cpu)[vmi_get_timer_vector()] = NULL;
> }
>
> #ifdef CONFIG_X86_LOCAL_APIC
> Index: linux/arch/x86/xen/irq.c
> ===================================================================
> --- linux.orig/arch/x86/xen/irq.c 2008-09-19 14:12:25.000000000 -0500
> +++ linux/arch/x86/xen/irq.c 2008-09-19 14:13:09.000000000 -0500
> @@ -27,8 +27,9 @@ static void __init __xen_init_IRQ(void)
> for(i = 0; i < NR_VECTORS; i++) {
> int cpu;
>
> + desc = irq_to_desc_alloc(i);
> for_each_possible_cpu(cpu)
> - per_cpu(vector_irq, cpu)[i] = i;
> + per_cpu(vector_irq, cpu)[i] = desc;
> }
>
> xen_init_IRQ();
> Index: linux/arch/x86/kernel/irqinit_32.c
> ===================================================================
> --- linux.orig/arch/x86/kernel/irqinit_32.c 2008-09-19 14:12:25.000000000 -0500
> +++ linux/arch/x86/kernel/irqinit_32.c 2008-09-19 14:13:09.000000000 -0500
> @@ -59,6 +59,8 @@ static struct irqaction fpu_irq = {
> void __init init_ISA_irqs (void)
> {
> int i;
> + int cpu;
> + unsigned int vector;
>
> #ifdef CONFIG_X86_LOCAL_APIC
> init_bsp_APIC();
> @@ -76,6 +78,12 @@ void __init init_ISA_irqs (void)
> desc->action = NULL;
> desc->depth = 1;
>
> + vector = IRQ0_VECTOR + i;
> + for_each_possible_cpu(cpu) {
> + BUG_ON(per_cpu(vector_irq, cpu)[vector] != NULL);
> + per_cpu(vector_irq, cpu)[vector] = desc;
> + }
> +
> set_irq_chip_and_handler_name(i, &i8259A_chip,
> handle_level_irq, "XT");
> }
> @@ -90,26 +98,7 @@ static struct irqaction irq2 = {
> .name = "cascade",
> };
>
> -DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
> - [0 ... IRQ0_VECTOR - 1] = -1,
> - [IRQ0_VECTOR] = 0,
> - [IRQ1_VECTOR] = 1,
> - [IRQ2_VECTOR] = 2,
> - [IRQ3_VECTOR] = 3,
> - [IRQ4_VECTOR] = 4,
> - [IRQ5_VECTOR] = 5,
> - [IRQ6_VECTOR] = 6,
> - [IRQ7_VECTOR] = 7,
> - [IRQ8_VECTOR] = 8,
> - [IRQ9_VECTOR] = 9,
> - [IRQ10_VECTOR] = 10,
> - [IRQ11_VECTOR] = 11,
> - [IRQ12_VECTOR] = 12,
> - [IRQ13_VECTOR] = 13,
> - [IRQ14_VECTOR] = 14,
> - [IRQ15_VECTOR] = 15,
> - [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
> -};
> +DEFINE_PER_CPU(vector_irq_t, vector_irq);
>
> /* Overridden in paravirt.c */
> void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
> Index: linux/arch/x86/kernel/irqinit_64.c
> ===================================================================
> --- linux.orig/arch/x86/kernel/irqinit_64.c 2008-09-19 14:12:25.000000000 -0500
> +++ linux/arch/x86/kernel/irqinit_64.c 2008-09-19 14:13:09.000000000 -0500
> @@ -114,30 +114,13 @@ static struct irqaction irq2 = {
> .mask = CPU_MASK_NONE,
> .name = "cascade",
> };
> -DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
> - [0 ... IRQ0_VECTOR - 1] = -1,
> - [IRQ0_VECTOR] = 0,
> - [IRQ1_VECTOR] = 1,
> - [IRQ2_VECTOR] = 2,
> - [IRQ3_VECTOR] = 3,
> - [IRQ4_VECTOR] = 4,
> - [IRQ5_VECTOR] = 5,
> - [IRQ6_VECTOR] = 6,
> - [IRQ7_VECTOR] = 7,
> - [IRQ8_VECTOR] = 8,
> - [IRQ9_VECTOR] = 9,
> - [IRQ10_VECTOR] = 10,
> - [IRQ11_VECTOR] = 11,
> - [IRQ12_VECTOR] = 12,
> - [IRQ13_VECTOR] = 13,
> - [IRQ14_VECTOR] = 14,
> - [IRQ15_VECTOR] = 15,
> - [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
> -};
> +DEFINE_PER_CPU(vector_irq_t, vector_irq);
>
> static void __init init_ISA_irqs (void)
> {
> int i;
> + int cpu;
> + unsigned int vector;
>
> init_bsp_APIC();
> init_8259A(0);
> @@ -150,6 +133,12 @@ static void __init init_ISA_irqs (void)
> desc->action = NULL;
> desc->depth = 1;
>
> + vector = IRQ0_VECTOR + i;
> + for_each_possible_cpu(cpu) {
> + BUG_ON(per_cpu(vector_irq, cpu)[vector] != NULL);
> + per_cpu(vector_irq, cpu)[vector] = desc;
> + }
> +
> /*
> * 16 old-style INTA-cycle interrupts:
> */
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2
2008-09-19 20:04 ` [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2 Dean Nelson
2008-09-19 20:24 ` Mike Travis
@ 2008-09-19 20:40 ` Yinghai Lu
2008-09-19 23:26 ` Dean Nelson
1 sibling, 1 reply; 11+ messages in thread
From: Yinghai Lu @ 2008-09-19 20:40 UTC (permalink / raw)
To: Dean Nelson
Cc: Ingo Molnar, Eric W. Biederman, H. Peter Anvin, Jack Steiner,
Alan Mayer, jeremy, rusty, suresh.b.siddha, torvalds,
linux-kernel, Thomas Gleixner, Yinghai Lu
On Fri, Sep 19, 2008 at 1:04 PM, Dean Nelson <dcn@sgi.com> wrote:
> Change per_cpu variable vector_irq[] from holding an 'int' irq number to
> holding a 'struct irq_desc' pointer.
why?
Eric wants to change int irq to some struct irq later?
YH
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2
2008-09-19 20:24 ` Mike Travis
@ 2008-09-19 23:17 ` Dean Nelson
2008-09-22 11:05 ` Ingo Molnar
1 sibling, 0 replies; 11+ messages in thread
From: Dean Nelson @ 2008-09-19 23:17 UTC (permalink / raw)
To: Mike Travis
Cc: Ingo Molnar, Eric W. Biederman, H. Peter Anvin, Jack Steiner,
Alan Mayer, jeremy, rusty, suresh.b.siddha, torvalds,
linux-kernel, Thomas Gleixner, Yinghai Lu
On Fri, Sep 19, 2008 at 01:24:55PM -0700, Mike Travis wrote:
>
> Note that my recent patch from a couple of weeks ago, stripped almost all of
> the cpumask_t's from the io_apic functions. Any chance we can apply them
> before we add more?
>
> I'd be willing to merge in Dean's patch over the top of mine (or vice-versa).
Sorry Mike, I didn't realize you had any patches against io_apic functions.
You might take a look at the second patch in this patchset, I tried to
eliminate some of the cpumask_t's from being defined on the stack and to
pass only pointers to them as args. I didn't do all that could be done,
but just the ones near the main functions I was touching. You may have a
better way of doing it then I did.
Feel free to do whatever with this patchset. (I'm not going to be
reachable until Monday.)
FYI, this patchset was built against linux-next.
Thanks,
Dean
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2
2008-09-19 20:40 ` Yinghai Lu
@ 2008-09-19 23:26 ` Dean Nelson
0 siblings, 0 replies; 11+ messages in thread
From: Dean Nelson @ 2008-09-19 23:26 UTC (permalink / raw)
To: Yinghai Lu
Cc: Ingo Molnar, Eric W. Biederman, H. Peter Anvin, Jack Steiner,
Alan Mayer, jeremy, rusty, suresh.b.siddha, torvalds,
linux-kernel, Thomas Gleixner, Yinghai Lu
On Fri, Sep 19, 2008 at 01:40:23PM -0700, Yinghai Lu wrote:
> On Fri, Sep 19, 2008 at 1:04 PM, Dean Nelson <dcn@sgi.com> wrote:
> > Change per_cpu variable vector_irq[] from holding an 'int' irq number to
> > holding a 'struct irq_desc' pointer.
>
> why?
>
> Eric wants to change int irq to some struct irq later?
Well, it was my take on what Eric was saying in the following:
On Mon, Aug 11, 2008 at 12:39:22PM -0700, Eric W. Biederman wrote:
>
> We create a common factor of assign_irq_vector that looks something like:
>
> bool __grab_irq_vector(struct irq_desc *desc, unsigned vector, cpumask_t new_domain)
> {
> /* Must be called with vector lock */
> struct irq_cfg *cfg;
> bool grabbed = false;
> unsigned int old_vector;
> cpumask_t mask;
> int cpu;
>
> cfg = get_irqp_cfg(irq);
> old_vector = cfg->vector;
> cpus_and(mask, new_domain, cpu_online_map);
>
> for_each_cpu_mask_nr(cpu, mask) {
> if (per_cpu(vector_irq, cpu)[vector])
> goto out;
> }
> /* Available reserve it */
> for_each_cpu_mask_nr(cpu, mask)
> per_cpu(vector_irq, cpu)[vector] = desc;
The previous line made me think that was what he wanted....
> if (cfg->vector) {
> cfg->move_in_progress;
> cfg->old_domain = cfg->domain;
> }
> cfg->vector = vector;
> cfg->domain = mask;
> grabbed = true;
>
> out:
> return grabbed;
> }
... Along with the following paragraph.
> I think vector_irq should return an irq_desc and have an entry for
> all of the static vectors as well (if we are going to do weird
> things with dynamic high priority vector allocation, and dynamic
> detection of which vectors assign_irq_vector may use).
If that's not what Eric meant, then I got it wrong and you can reject
the patchset.
Dean
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2
2008-09-19 20:24 ` Mike Travis
2008-09-19 23:17 ` Dean Nelson
@ 2008-09-22 11:05 ` Ingo Molnar
2008-09-22 15:12 ` Mike Travis
1 sibling, 1 reply; 11+ messages in thread
From: Ingo Molnar @ 2008-09-22 11:05 UTC (permalink / raw)
To: Mike Travis, Rusty Russell
Cc: Dean Nelson, Eric W. Biederman, H. Peter Anvin, Jack Steiner,
Alan Mayer, jeremy, rusty, suresh.b.siddha, torvalds,
linux-kernel, Thomas Gleixner, Yinghai Lu
* Mike Travis <travis@sgi.com> wrote:
> Hi Ingo,
>
> Note that my recent patch from a couple of weeks ago, stripped almost
> all of the cpumask_t's from the io_apic functions. Any chance we can
> apply them before we add more?
>
> I'd be willing to merge in Dean's patch over the top of mine (or
> vice-versa).
i'm really looking forwards to Rusty's 'get-rid-of-cpumask_t use'
patchset, which would solve such cpumask_t proliferation issues once and
for all.
Ingo
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2
2008-09-22 11:05 ` Ingo Molnar
@ 2008-09-22 15:12 ` Mike Travis
2008-09-22 15:44 ` Mike Travis
0 siblings, 1 reply; 11+ messages in thread
From: Mike Travis @ 2008-09-22 15:12 UTC (permalink / raw)
To: Ingo Molnar
Cc: Rusty Russell, Dean Nelson, Eric W. Biederman, H. Peter Anvin,
Jack Steiner, Alan Mayer, jeremy, suresh.b.siddha, torvalds,
linux-kernel, Thomas Gleixner, Yinghai Lu
Ingo Molnar wrote:
> * Mike Travis <travis@sgi.com> wrote:
>
>> Hi Ingo,
>>
>> Note that my recent patch from a couple of weeks ago, stripped almost
>> all of the cpumask_t's from the io_apic functions. Any chance we can
>> apply them before we add more?
>>
>> I'd be willing to merge in Dean's patch over the top of mine (or
>> vice-versa).
>
> i'm really looking forwards to Rusty's 'get-rid-of-cpumask_t use'
> patchset, which would solve such cpumask_t proliferation issues once and
> for all.
>
> Ingo
Hi Ingo,
The net effect of the "getting rid of cpumask_t's" will be the same. This
patch reduces considerably the amount of stack space being required right
now. The new cpumask_t approach will take quite a bit of time to get it
"up and running". (It took me about a day to get init/main.c and kernel/sched.c
to just compile... it now needs the temp cpumasks to actually function. And
there are a number of areas that will need to be altered before functional
testing can start.)
Thanks,
Mike
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2
2008-09-22 15:12 ` Mike Travis
@ 2008-09-22 15:44 ` Mike Travis
0 siblings, 0 replies; 11+ messages in thread
From: Mike Travis @ 2008-09-22 15:44 UTC (permalink / raw)
To: Ingo Molnar
Cc: Rusty Russell, Dean Nelson, Eric W. Biederman, H. Peter Anvin,
Jack Steiner, Alan Mayer, jeremy, suresh.b.siddha, torvalds,
linux-kernel, Thomas Gleixner, Yinghai Lu
Mike Travis wrote:
> Ingo Molnar wrote:
>> * Mike Travis <travis@sgi.com> wrote:
>>
>>> Hi Ingo,
>>>
>>> Note that my recent patch from a couple of weeks ago, stripped almost
>>> all of the cpumask_t's from the io_apic functions. Any chance we can
>>> apply them before we add more?
>>>
>>> I'd be willing to merge in Dean's patch over the top of mine (or
>>> vice-versa).
>> i'm really looking forwards to Rusty's 'get-rid-of-cpumask_t use'
>> patchset, which would solve such cpumask_t proliferation issues once and
>> for all.
>>
>> Ingo
>
> Hi Ingo,
>
> The net effect of the "getting rid of cpumask_t's" will be the same. This
> patch reduces considerably the amount of stack space being required right
> now.
Btw, my patch will still be useful even after cpumask's are passed by reference
in that it optimizes the cpumask's that are being used. For example, in one
function 3 cpumask_t's become 1. In some others, 2 were reduced to 1. Since
the new cpumask approach will require temp cpumask's, this cuts down on the
number of temp cpumask's required.
Thanks,
Mike
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-09-22 15:45 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-19 20:02 [PATCH 0/3] unify the allocation of irq vectors v2 Dean Nelson
2008-09-19 20:04 ` [PATCH 1/3] switch vector_irq[] from irq number to irq_desc pointer v2 Dean Nelson
2008-09-19 20:24 ` Mike Travis
2008-09-19 23:17 ` Dean Nelson
2008-09-22 11:05 ` Ingo Molnar
2008-09-22 15:12 ` Mike Travis
2008-09-22 15:44 ` Mike Travis
2008-09-19 20:40 ` Yinghai Lu
2008-09-19 23:26 ` Dean Nelson
2008-09-19 20:06 ` [PATCH 2/3] switch static system vector allocation to use vector_irq[] v2 Dean Nelson
2008-09-19 20:08 ` [PATCH 3/3] switch non-standard SYSCALL_VECTOR allocation to use vector_irq v2 Dean Nelson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).