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

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

[PATCH] x86_64 irq: Simplify assign_irq_vector's arguments.



Currently assign_irq_vector works mostly by side effect and returns
the results of it's changes to the caller.  Which makes for a lot of
arguments to pass/return and confusion as to what to do if you need
the status but you aren't calling assign_irq_vector.

This patch stops returning values from assign_irq_vector that can be
retrieved just as easily by examining irq_cfg, and modifies the
callers to retrive those values from irq_cfg when they need them.

Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 13a79503
Loading
Loading
Loading
Loading
+56 −53
Original line number Original line Diff line number Diff line
@@ -72,7 +72,7 @@ struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = {
	[15] = { .domain = CPU_MASK_ALL, .vector = FIRST_EXTERNAL_VECTOR + 15 },
	[15] = { .domain = CPU_MASK_ALL, .vector = FIRST_EXTERNAL_VECTOR + 15 },
};
};


static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result);
static int assign_irq_vector(int irq, cpumask_t mask);


#define __apicdebuginit  __init
#define __apicdebuginit  __init


@@ -262,19 +262,19 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, u8 vector)


static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
{
{
	struct irq_cfg *cfg = irq_cfg + irq;
	unsigned long flags;
	unsigned long flags;
	unsigned int dest;
	unsigned int dest;
	cpumask_t tmp;
	cpumask_t tmp;
	int vector;


	cpus_and(tmp, mask, cpu_online_map);
	cpus_and(tmp, mask, cpu_online_map);
	if (cpus_empty(tmp))
	if (cpus_empty(tmp))
		return;
		return;


	vector = assign_irq_vector(irq, mask, &tmp);
	if (assign_irq_vector(irq, mask))
	if (vector < 0)
		return;
		return;


	cpus_and(tmp, cfg->domain, mask);
	dest = cpu_mask_to_apicid(tmp);
	dest = cpu_mask_to_apicid(tmp);


	/*
	/*
@@ -283,7 +283,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
	dest = SET_APIC_LOGICAL_ID(dest);
	dest = SET_APIC_LOGICAL_ID(dest);


	spin_lock_irqsave(&ioapic_lock, flags);
	spin_lock_irqsave(&ioapic_lock, flags);
	__target_IO_APIC_irq(irq, dest, vector);
	__target_IO_APIC_irq(irq, dest, cfg->vector);
	irq_desc[irq].affinity = mask;
	irq_desc[irq].affinity = mask;
	spin_unlock_irqrestore(&ioapic_lock, flags);
	spin_unlock_irqrestore(&ioapic_lock, flags);
}
}
@@ -638,7 +638,7 @@ static int pin_2_irq(int idx, int apic, int pin)
	return irq;
	return irq;
}
}


static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
static int __assign_irq_vector(int irq, cpumask_t mask)
{
{
	/*
	/*
	 * NOTE! The local APIC isn't very good at handling
	 * NOTE! The local APIC isn't very good at handling
@@ -653,7 +653,7 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
	 */
	 */
	static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
	static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
	cpumask_t old_mask = CPU_MASK_NONE;
	cpumask_t old_mask = CPU_MASK_NONE;
	int old_vector = -1;
	unsigned int old_vector;
	int cpu;
	int cpu;
	struct irq_cfg *cfg;
	struct irq_cfg *cfg;


@@ -663,12 +663,12 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
	/* Only try and allocate irqs on cpus that are present */
	/* Only try and allocate irqs on cpus that are present */
	cpus_and(mask, mask, cpu_online_map);
	cpus_and(mask, mask, cpu_online_map);


	if (cfg->vector > 0)
	old_vector = cfg->vector;
	old_vector = cfg->vector;
	if (old_vector > 0) {
	if (old_vector) {
		cpus_and(*result, cfg->domain, mask);
		cpumask_t tmp;
		if (!cpus_empty(*result))
		cpus_and(tmp, cfg->domain, mask);
			return old_vector;
		if (!cpus_empty(tmp))
			return 0;
		cpus_and(old_mask, cfg->domain, cpu_online_map);
		cpus_and(old_mask, cfg->domain, cpu_online_map);
	}
	}


@@ -705,21 +705,20 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
			per_cpu(vector_irq, new_cpu)[vector] = irq;
			per_cpu(vector_irq, new_cpu)[vector] = irq;
		cfg->vector = vector;
		cfg->vector = vector;
		cfg->domain = domain;
		cfg->domain = domain;
		cpus_and(*result, domain, mask);
		return 0;
		return vector;
	}
	}
	return -ENOSPC;
	return -ENOSPC;
}
}


static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
static int assign_irq_vector(int irq, cpumask_t mask)
{
{
	int vector;
	int err;
	unsigned long flags;
	unsigned long flags;


	spin_lock_irqsave(&vector_lock, flags);
	spin_lock_irqsave(&vector_lock, flags);
	vector = __assign_irq_vector(irq, mask, result);
	err = __assign_irq_vector(irq, mask);
	spin_unlock_irqrestore(&vector_lock, flags);
	spin_unlock_irqrestore(&vector_lock, flags);
	return vector;
	return err;
}
}


static void __clear_irq_vector(int irq)
static void __clear_irq_vector(int irq)
@@ -780,22 +779,24 @@ static void ioapic_register_intr(int irq, unsigned long trigger)
static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq,
static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq,
			      int trigger, int polarity)
			      int trigger, int polarity)
{
{
	struct irq_cfg *cfg = irq_cfg + irq;
	struct IO_APIC_route_entry entry;
	struct IO_APIC_route_entry entry;
	cpumask_t mask;
	cpumask_t mask;
	int vector;
	unsigned long flags;
	unsigned long flags;


	if (!IO_APIC_IRQ(irq))
	if (!IO_APIC_IRQ(irq))
		return;
		return;


	vector = assign_irq_vector(irq, TARGET_CPUS, &mask);
	mask = TARGET_CPUS;
	if (vector < 0)
	if (assign_irq_vector(irq, mask))
		return;
		return;


	cpus_and(mask, cfg->domain, mask);

	apic_printk(APIC_VERBOSE,KERN_DEBUG
	apic_printk(APIC_VERBOSE,KERN_DEBUG
		    "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> "
		    "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> "
		    "IRQ %d Mode:%i Active:%i)\n",
		    "IRQ %d Mode:%i Active:%i)\n",
		    apic, mp_ioapics[apic].mpc_apicid, pin, vector,
		    apic, mp_ioapics[apic].mpc_apicid, pin, cfg->vector,
		    irq, trigger, polarity);
		    irq, trigger, polarity);


	/*
	/*
@@ -809,7 +810,7 @@ static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq,
	entry.mask = 0;				/* enable IRQ */
	entry.mask = 0;				/* enable IRQ */
	entry.trigger = trigger;
	entry.trigger = trigger;
	entry.polarity = polarity;
	entry.polarity = polarity;
	entry.vector = vector;
	entry.vector = cfg->vector;


	/* Mask level triggered irqs.
	/* Mask level triggered irqs.
	 * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
	 * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
@@ -1558,15 +1559,14 @@ static inline void unlock_ExtINT_logic(void)
 */
 */
static inline void check_timer(void)
static inline void check_timer(void)
{
{
	struct irq_cfg *cfg = irq_cfg + 0;
	int apic1, pin1, apic2, pin2;
	int apic1, pin1, apic2, pin2;
	int vector;
	cpumask_t mask;


	/*
	/*
	 * get/set the timer IRQ vector:
	 * get/set the timer IRQ vector:
	 */
	 */
	disable_8259A_irq(0);
	disable_8259A_irq(0);
	vector = assign_irq_vector(0, TARGET_CPUS, &mask);
	assign_irq_vector(0, TARGET_CPUS);


	/*
	/*
	 * Subtle, code in do_timer_interrupt() expects an AEOI
	 * Subtle, code in do_timer_interrupt() expects an AEOI
@@ -1586,7 +1586,7 @@ static inline void check_timer(void)
	apic2 = ioapic_i8259.apic;
	apic2 = ioapic_i8259.apic;


	apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
	apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
		vector, apic1, pin1, apic2, pin2);
		cfg->vector, apic1, pin1, apic2, pin2);


	if (pin1 != -1) {
	if (pin1 != -1) {
		/*
		/*
@@ -1617,7 +1617,7 @@ static inline void check_timer(void)
		/*
		/*
		 * legacy devices should be connected to IO APIC #0
		 * legacy devices should be connected to IO APIC #0
		 */
		 */
		setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
		setup_ExtINT_IRQ0_pin(apic2, pin2, cfg->vector);
		if (timer_irq_works()) {
		if (timer_irq_works()) {
			apic_printk(APIC_VERBOSE," works.\n");
			apic_printk(APIC_VERBOSE," works.\n");
			nmi_watchdog_default();
			nmi_watchdog_default();
@@ -1642,14 +1642,14 @@ static inline void check_timer(void)


	disable_8259A_irq(0);
	disable_8259A_irq(0);
	irq_desc[0].chip = &lapic_irq_type;
	irq_desc[0].chip = &lapic_irq_type;
	apic_write(APIC_LVT0, APIC_DM_FIXED | vector);	/* Fixed mode */
	apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);	/* Fixed mode */
	enable_8259A_irq(0);
	enable_8259A_irq(0);


	if (timer_irq_works()) {
	if (timer_irq_works()) {
		apic_printk(APIC_VERBOSE," works.\n");
		apic_printk(APIC_VERBOSE," works.\n");
		return;
		return;
	}
	}
	apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
	apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
	apic_printk(APIC_VERBOSE," failed.\n");
	apic_printk(APIC_VERBOSE," failed.\n");


	apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as ExtINT IRQ...");
	apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as ExtINT IRQ...");
@@ -1796,9 +1796,7 @@ int create_irq(void)
	/* Allocate an unused irq */
	/* Allocate an unused irq */
	int irq;
	int irq;
	int new;
	int new;
	int vector = 0;
	unsigned long flags;
	unsigned long flags;
	cpumask_t mask;


	irq = -ENOSPC;
	irq = -ENOSPC;
	spin_lock_irqsave(&vector_lock, flags);
	spin_lock_irqsave(&vector_lock, flags);
@@ -1807,8 +1805,7 @@ int create_irq(void)
			continue;
			continue;
		if (irq_cfg[new].vector != 0)
		if (irq_cfg[new].vector != 0)
			continue;
			continue;
		vector = __assign_irq_vector(new, TARGET_CPUS, &mask);
		if (__assign_irq_vector(new, TARGET_CPUS) == 0)
		if (likely(vector > 0))
			irq = new;
			irq = new;
		break;
		break;
	}
	}
@@ -1837,12 +1834,15 @@ void destroy_irq(unsigned int irq)
#ifdef CONFIG_PCI_MSI
#ifdef CONFIG_PCI_MSI
static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
{
{
	int vector;
	struct irq_cfg *cfg = irq_cfg + irq;
	int err;
	unsigned dest;
	unsigned dest;
	cpumask_t tmp;
	cpumask_t tmp;


	vector = assign_irq_vector(irq, TARGET_CPUS, &tmp);
	tmp = TARGET_CPUS;
	if (vector >= 0) {
	err = assign_irq_vector(irq, tmp);
	if (!err) {
		cpus_and(tmp, cfg->domain, tmp);
		dest = cpu_mask_to_apicid(tmp);
		dest = cpu_mask_to_apicid(tmp);


		msg->address_hi = MSI_ADDR_BASE_HI;
		msg->address_hi = MSI_ADDR_BASE_HI;
@@ -1862,33 +1862,33 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
			((INT_DELIVERY_MODE != dest_LowestPrio) ?
			((INT_DELIVERY_MODE != dest_LowestPrio) ?
				MSI_DATA_DELIVERY_FIXED:
				MSI_DATA_DELIVERY_FIXED:
				MSI_DATA_DELIVERY_LOWPRI) |
				MSI_DATA_DELIVERY_LOWPRI) |
			MSI_DATA_VECTOR(vector);
			MSI_DATA_VECTOR(cfg->vector);
	}
	}
	return vector;
	return err;
}
}


#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
{
{
	struct irq_cfg *cfg = irq_cfg + irq;
	struct msi_msg msg;
	struct msi_msg msg;
	unsigned int dest;
	unsigned int dest;
	cpumask_t tmp;
	cpumask_t tmp;
	int vector;


	cpus_and(tmp, mask, cpu_online_map);
	cpus_and(tmp, mask, cpu_online_map);
	if (cpus_empty(tmp))
	if (cpus_empty(tmp))
		return;
		return;


	vector = assign_irq_vector(irq, mask, &tmp);
	if (assign_irq_vector(irq, mask))
	if (vector < 0)
		return;
		return;


	cpus_and(tmp, cfg->domain, mask);
	dest = cpu_mask_to_apicid(tmp);
	dest = cpu_mask_to_apicid(tmp);


	read_msi_msg(irq, &msg);
	read_msi_msg(irq, &msg);


	msg.data &= ~MSI_DATA_VECTOR_MASK;
	msg.data &= ~MSI_DATA_VECTOR_MASK;
	msg.data |= MSI_DATA_VECTOR(vector);
	msg.data |= MSI_DATA_VECTOR(cfg->vector);
	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
	msg.address_lo |= MSI_ADDR_DEST_ID(dest);


@@ -1964,21 +1964,21 @@ static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)


static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
{
{
	struct irq_cfg *cfg = irq_cfg + irq;
	unsigned int dest;
	unsigned int dest;
	cpumask_t tmp;
	cpumask_t tmp;
	int vector;


	cpus_and(tmp, mask, cpu_online_map);
	cpus_and(tmp, mask, cpu_online_map);
	if (cpus_empty(tmp))
	if (cpus_empty(tmp))
		return;
		return;


	vector = assign_irq_vector(irq, mask, &tmp);
	if (assign_irq_vector(irq, mask))
	if (vector < 0)
		return;
		return;


	cpus_and(tmp, cfg->domain, mask);
	dest = cpu_mask_to_apicid(tmp);
	dest = cpu_mask_to_apicid(tmp);


	target_ht_irq(irq, dest, vector);
	target_ht_irq(irq, dest, cfg->vector);
	irq_desc[irq].affinity = mask;
	irq_desc[irq].affinity = mask;
}
}
#endif
#endif
@@ -1996,14 +1996,17 @@ static struct irq_chip ht_irq_chip = {


int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
{
{
	int vector;
	struct irq_cfg *cfg = irq_cfg + irq;
	int err;
	cpumask_t tmp;
	cpumask_t tmp;


	vector = assign_irq_vector(irq, TARGET_CPUS, &tmp);
	tmp = TARGET_CPUS;
	if (vector >= 0) {
	err = assign_irq_vector(irq, tmp);
	if (!err) {
		struct ht_irq_msg msg;
		struct ht_irq_msg msg;
		unsigned dest;
		unsigned dest;


		cpus_and(tmp, cfg->domain, tmp);
		dest = cpu_mask_to_apicid(tmp);
		dest = cpu_mask_to_apicid(tmp);


		msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);
		msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);
@@ -2011,7 +2014,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
		msg.address_lo =
		msg.address_lo =
			HT_IRQ_LOW_BASE |
			HT_IRQ_LOW_BASE |
			HT_IRQ_LOW_DEST_ID(dest) |
			HT_IRQ_LOW_DEST_ID(dest) |
			HT_IRQ_LOW_VECTOR(vector) |
			HT_IRQ_LOW_VECTOR(cfg->vector) |
			((INT_DEST_MODE == 0) ?
			((INT_DEST_MODE == 0) ?
				HT_IRQ_LOW_DM_PHYSICAL :
				HT_IRQ_LOW_DM_PHYSICAL :
				HT_IRQ_LOW_DM_LOGICAL) |
				HT_IRQ_LOW_DM_LOGICAL) |
@@ -2026,7 +2029,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
		set_irq_chip_and_handler_name(irq, &ht_irq_chip,
		set_irq_chip_and_handler_name(irq, &ht_irq_chip,
					      handle_edge_irq, "edge");
					      handle_edge_irq, "edge");
	}
	}
	return vector;
	return err;
}
}
#endif /* CONFIG_HT_IRQ */
#endif /* CONFIG_HT_IRQ */