* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.