Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04b9267b authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Linus Torvalds
Browse files

[PATCH] genirq: x86_64 irq: Remove the msi assumption that irq == vector



This patch removes the change in behavior of the irq allocation code when
CONFIG_PCI_MSI is defined.  Removing all instances of the assumption that irq
== vector.

create_irq is rewritten to first allocate a free irq and then to assign that
irq a vector.

assign_irq_vector is made static and the AUTO_ASSIGN case which allocates an
vector not bound to an irq is removed.

The ioapic vector methods are removed, and everything now works with irqs.

The definition of NR_IRQS no longer depends on CONFIG_PCI_MSI

Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rajesh Shah <rajesh.shah@intel.com>
Cc: Andi Kleen <ak@muc.de>
Cc: "Protasevich, Natalie" <Natalie.Protasevich@UNISYS.com>
Cc: "Luck, Tony" <tony.luck@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 4b2fabb9
Loading
Loading
Loading
Loading
+47 −100
Original line number Original line Diff line number Diff line
@@ -44,6 +44,8 @@
#include <asm/nmi.h>
#include <asm/nmi.h>
#include <asm/msidef.h>
#include <asm/msidef.h>


static int assign_irq_vector(int irq);

#define __apicdebuginit  __init
#define __apicdebuginit  __init


int sis_apic_bug; /* not actually supported, dummy for compile */
int sis_apic_bug; /* not actually supported, dummy for compile */
@@ -83,14 +85,6 @@ static struct irq_pin_list {
	short apic, pin, next;
	short apic, pin, next;
} irq_2_pin[PIN_MAP_SIZE];
} irq_2_pin[PIN_MAP_SIZE];


int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
#ifdef CONFIG_PCI_MSI
#define vector_to_irq(vector) 	\
	(platform_legacy_irq(vector) ? vector : vector_irq[vector])
#else
#define vector_to_irq(vector)	(vector)
#endif

#define __DO_ACTION(R, ACTION, FINAL)					\
#define __DO_ACTION(R, ACTION, FINAL)					\
									\
									\
{									\
{									\
@@ -162,7 +156,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)


	spin_lock_irqsave(&ioapic_lock, flags);
	spin_lock_irqsave(&ioapic_lock, flags);
	__DO_ACTION(1, = dest, )
	__DO_ACTION(1, = dest, )
	set_irq_info(irq, mask);
	set_native_irq_info(irq, mask);
	spin_unlock_irqrestore(&ioapic_lock, flags);
	spin_unlock_irqrestore(&ioapic_lock, flags);
}
}
#endif
#endif
@@ -599,18 +593,14 @@ static inline int IO_APIC_irq_trigger(int irq)
/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };


int assign_irq_vector(int irq)
static int __assign_irq_vector(int irq)
{
{
	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
	unsigned long flags;
	int vector;
	int vector;


	BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
	BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);

	spin_lock_irqsave(&vector_lock, flags);


	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
	if (IO_APIC_VECTOR(irq) > 0) {
		spin_unlock_irqrestore(&vector_lock, flags);
		return IO_APIC_VECTOR(irq);
		return IO_APIC_VECTOR(irq);
	}
	}
next:
next:
@@ -625,10 +615,18 @@ int assign_irq_vector(int irq)
	}
	}


	vector = current_vector;
	vector = current_vector;
	vector_irq[vector] = irq;
	if (irq != AUTO_ASSIGN)
	IO_APIC_VECTOR(irq) = vector;
	IO_APIC_VECTOR(irq) = vector;


	return vector;
}

static int assign_irq_vector(int irq)
{
	int vector;
	unsigned long flags;

	spin_lock_irqsave(&vector_lock, flags);
	vector = __assign_irq_vector(irq);
	spin_unlock_irqrestore(&vector_lock, flags);
	spin_unlock_irqrestore(&vector_lock, flags);


	return vector;
	return vector;
@@ -644,18 +642,14 @@ static struct irq_chip ioapic_chip;


static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
{
{
	unsigned idx;

	idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq;

	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
			trigger == IOAPIC_LEVEL)
			trigger == IOAPIC_LEVEL)
		set_irq_chip_and_handler(idx, &ioapic_chip,
		set_irq_chip_and_handler(irq, &ioapic_chip,
					 handle_fasteoi_irq);
					 handle_fasteoi_irq);
	else
	else
		set_irq_chip_and_handler(idx, &ioapic_chip,
		set_irq_chip_and_handler(irq, &ioapic_chip,
					 handle_edge_irq);
					 handle_edge_irq);
	set_intr_gate(vector, interrupt[idx]);
	set_intr_gate(vector, interrupt[irq]);
}
}


static void __init setup_IO_APIC_irqs(void)
static void __init setup_IO_APIC_irqs(void)
@@ -872,16 +866,11 @@ void __apicdebuginit print_IO_APIC(void)
		);
		);
	}
	}
	}
	}
	if (use_pci_vector())
		printk(KERN_INFO "Using vector-based indexing\n");
	printk(KERN_DEBUG "IRQ to pin mappings:\n");
	printk(KERN_DEBUG "IRQ to pin mappings:\n");
	for (i = 0; i < NR_IRQS; i++) {
	for (i = 0; i < NR_IRQS; i++) {
		struct irq_pin_list *entry = irq_2_pin + i;
		struct irq_pin_list *entry = irq_2_pin + i;
		if (entry->pin < 0)
		if (entry->pin < 0)
			continue;
			continue;
 		if (use_pci_vector() && !platform_legacy_irq(i))
			printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i));
		else
		printk(KERN_DEBUG "IRQ%d ", i);
		printk(KERN_DEBUG "IRQ%d ", i);
		for (;;) {
		for (;;) {
			printk("-> %d:%d", entry->apic, entry->pin);
			printk("-> %d:%d", entry->apic, entry->pin);
@@ -1206,42 +1195,8 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
	return was_pending;
	return was_pending;
}
}


static unsigned int startup_ioapic_vector(unsigned int vector)
static int ioapic_retrigger_irq(unsigned int irq)
{
	int irq = vector_to_irq(vector);

	return startup_ioapic_irq(irq);
}

static void mask_ioapic_vector (unsigned int vector)
{
	int irq = vector_to_irq(vector);

	mask_IO_APIC_irq(irq);
}

static void unmask_ioapic_vector (unsigned int vector)
{
	int irq = vector_to_irq(vector);

	unmask_IO_APIC_irq(irq);
}

#ifdef CONFIG_SMP
static void set_ioapic_affinity_vector (unsigned int vector,
					cpumask_t cpu_mask)
{
{
	int irq = vector_to_irq(vector);

	set_native_irq_info(vector, cpu_mask);
	set_ioapic_affinity_irq(irq, cpu_mask);
}
#endif // CONFIG_SMP

static int ioapic_retrigger_vector(unsigned int vector)
{
	int irq = vector_to_irq(vector);

	send_IPI_self(IO_APIC_VECTOR(irq));
	send_IPI_self(IO_APIC_VECTOR(irq));


	return 1;
	return 1;
@@ -1288,15 +1243,15 @@ static void ack_apic_level(unsigned int irq)


static struct irq_chip ioapic_chip __read_mostly = {
static struct irq_chip ioapic_chip __read_mostly = {
	.name 		= "IO-APIC",
	.name 		= "IO-APIC",
	.startup 	= startup_ioapic_vector,
	.startup 	= startup_ioapic_irq,
	.mask	 	= mask_ioapic_vector,
	.mask	 	= mask_IO_APIC_irq,
	.unmask	 	= unmask_ioapic_vector,
	.unmask	 	= unmask_IO_APIC_irq,
	.ack 		= ack_apic_edge,
	.ack 		= ack_apic_edge,
	.eoi 		= ack_apic_level,
	.eoi 		= ack_apic_level,
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
	.set_affinity 	= set_ioapic_affinity_vector,
	.set_affinity 	= set_ioapic_affinity_irq,
#endif
#endif
	.retrigger	= ioapic_retrigger_vector,
	.retrigger	= ioapic_retrigger_irq,
};
};


static inline void init_IO_APIC_traps(void)
static inline void init_IO_APIC_traps(void)
@@ -1316,11 +1271,6 @@ static inline void init_IO_APIC_traps(void)
	 */
	 */
	for (irq = 0; irq < NR_IRQS ; irq++) {
	for (irq = 0; irq < NR_IRQS ; irq++) {
		int tmp = irq;
		int tmp = irq;
		if (use_pci_vector()) {
			if (!platform_legacy_irq(tmp))
				if ((tmp = vector_to_irq(tmp)) == -1)
					continue;
		}
		if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
		if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
			/*
			/*
			 * Hmm.. We don't have an entry for this,
			 * Hmm.. We don't have an entry for this,
@@ -1695,32 +1645,33 @@ static int __init ioapic_init_sysfs(void)


device_initcall(ioapic_init_sysfs);
device_initcall(ioapic_init_sysfs);


#ifdef CONFIG_PCI_MSI
/*
/*
 * Dynamic irq allocate and deallocation for MSI
 * Dynamic irq allocate and deallocation
 */
 */
int create_irq(void)
int create_irq(void)
{
{
	/* Hack of the day: irq == vector.
	/* Allocate an unused irq */
	 *
	int irq;
	 * Ultimately this will be be more general,
	int new;
	 * and not depend on the irq to vector identity mapping.
	int vector = 0;
	 * But this version is needed until msi.c can cope with
	 * the more general form.
	 */
	int irq, vector;
	unsigned long flags;
	unsigned long flags;
	vector = assign_irq_vector(AUTO_ASSIGN);
	irq = vector;


	if (vector >= 0) {
	irq = -ENOSPC;
	spin_lock_irqsave(&vector_lock, flags);
	spin_lock_irqsave(&vector_lock, flags);
		vector_irq[vector] = irq;
	for (new = (NR_IRQS - 1); new >= 0; new--) {
		irq_vector[irq] = vector;
		if (platform_legacy_irq(new))
			continue;
		if (irq_vector[new] != 0)
			continue;
		vector = __assign_irq_vector(new);
		if (likely(vector > 0))
			irq = new;
		break;
	}
	spin_unlock_irqrestore(&vector_lock, flags);
	spin_unlock_irqrestore(&vector_lock, flags);


	if (irq >= 0) {
		set_intr_gate(vector, interrupt[irq]);
		set_intr_gate(vector, interrupt[irq]);

		dynamic_irq_init(irq);
		dynamic_irq_init(irq);
	}
	}
	return irq;
	return irq;
@@ -1729,17 +1680,13 @@ int create_irq(void)
void destroy_irq(unsigned int irq)
void destroy_irq(unsigned int irq)
{
{
	unsigned long flags;
	unsigned long flags;
	unsigned int vector;


	dynamic_irq_cleanup(irq);
	dynamic_irq_cleanup(irq);


	spin_lock_irqsave(&vector_lock, flags);
	spin_lock_irqsave(&vector_lock, flags);
	vector = irq_vector[irq];
	vector_irq[vector] = -1;
	irq_vector[irq] = 0;
	irq_vector[irq] = 0;
	spin_unlock_irqrestore(&vector_lock, flags);
	spin_unlock_irqrestore(&vector_lock, flags);
}
}
#endif


/*
/*
 * MSI mesage composition
 * MSI mesage composition
@@ -1882,7 +1829,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
	ioapic_write_entry(ioapic, pin, entry);
	ioapic_write_entry(ioapic, pin, entry);


	spin_lock_irqsave(&ioapic_lock, flags);
	spin_lock_irqsave(&ioapic_lock, flags);
	set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS);
	set_native_irq_info(irq, TARGET_CPUS);
	spin_unlock_irqrestore(&ioapic_lock, flags);
	spin_unlock_irqrestore(&ioapic_lock, flags);


	return 0;
	return 0;
+0 −1
Original line number Original line Diff line number Diff line
@@ -75,7 +75,6 @@
#ifndef __ASSEMBLY__
#ifndef __ASSEMBLY__
extern u8 irq_vector[NR_IRQ_VECTORS];
extern u8 irq_vector[NR_IRQ_VECTORS];
#define IO_APIC_VECTOR(irq)	(irq_vector[irq])
#define IO_APIC_VECTOR(irq)	(irq_vector[irq])
#define AUTO_ASSIGN		-1


/*
/*
 * Various low-level irq details needed by irq.c, process.c,
 * Various low-level irq details needed by irq.c, process.c,
+0 −40
Original line number Original line Diff line number Diff line
@@ -10,45 +10,7 @@
 * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar
 * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar
 */
 */


#ifdef CONFIG_PCI_MSI
static inline int use_pci_vector(void)	{return 1;}
static inline void disable_edge_ioapic_vector(unsigned int vector) { }
static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
static inline void end_edge_ioapic_vector (unsigned int vector) { }
#define startup_level_ioapic	startup_level_ioapic_vector
#define shutdown_level_ioapic	mask_IO_APIC_vector
#define enable_level_ioapic	unmask_IO_APIC_vector
#define disable_level_ioapic	mask_IO_APIC_vector
#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector
#define end_level_ioapic	end_level_ioapic_vector
#define set_ioapic_affinity	set_ioapic_affinity_vector

#define startup_edge_ioapic 	startup_edge_ioapic_vector
#define shutdown_edge_ioapic 	disable_edge_ioapic_vector
#define enable_edge_ioapic 	unmask_IO_APIC_vector
#define disable_edge_ioapic 	disable_edge_ioapic_vector
#define ack_edge_ioapic 	ack_edge_ioapic_vector
#define end_edge_ioapic 	end_edge_ioapic_vector
#else
static inline int use_pci_vector(void)	{return 0;}
static inline int use_pci_vector(void)	{return 0;}
static inline void disable_edge_ioapic_irq(unsigned int irq) { }
static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
static inline void end_edge_ioapic_irq (unsigned int irq) { }
#define startup_level_ioapic	startup_level_ioapic_irq
#define shutdown_level_ioapic	mask_IO_APIC_irq
#define enable_level_ioapic	unmask_IO_APIC_irq
#define disable_level_ioapic	mask_IO_APIC_irq
#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq
#define end_level_ioapic	end_level_ioapic_irq
#define set_ioapic_affinity	set_ioapic_affinity_irq

#define startup_edge_ioapic 	startup_edge_ioapic_irq
#define shutdown_edge_ioapic 	disable_edge_ioapic_irq
#define enable_edge_ioapic 	unmask_IO_APIC_irq
#define disable_edge_ioapic 	disable_edge_ioapic_irq
#define ack_edge_ioapic 	ack_edge_ioapic_irq
#define end_edge_ioapic 	end_edge_ioapic_irq
#endif


#define APIC_MISMATCH_DEBUG
#define APIC_MISMATCH_DEBUG


@@ -207,8 +169,6 @@ extern int timer_uses_ioapic_pin_0;


extern int sis_apic_bug; /* dummy */ 
extern int sis_apic_bug; /* dummy */ 


extern int assign_irq_vector(int irq);

void enable_NMI_through_LVT0 (void * dummy);
void enable_NMI_through_LVT0 (void * dummy);


extern spinlock_t i8259A_lock;
extern spinlock_t i8259A_lock;
+0 −5
Original line number Original line Diff line number Diff line
@@ -31,13 +31,8 @@


#define FIRST_SYSTEM_VECTOR	0xef   /* duplicated in hw_irq.h */
#define FIRST_SYSTEM_VECTOR	0xef   /* duplicated in hw_irq.h */


#ifdef CONFIG_PCI_MSI
#define NR_IRQS FIRST_SYSTEM_VECTOR
#define NR_IRQ_VECTORS NR_IRQS
#else
#define NR_IRQS 224
#define NR_IRQS 224
#define NR_IRQ_VECTORS (32 * NR_CPUS)
#define NR_IRQ_VECTORS (32 * NR_CPUS)
#endif


static __inline__ int irq_canonicalize(int irq)
static __inline__ int irq_canonicalize(int irq)
{
{