x86/pci: update pirq_enable_irq() to setup io apic routing
So we can set io apic routing only when enabling the device irq. This is advantageous for IRQ descriptor allocation affinity: if we set up the IO-APIC entry later, we have a chance to allocate the IRQ descriptor later and know which device it is on and can set affinity accordingly. [ Impact: standardize/enhance irq-enabling sequence for mptable irqs ] Signed-off-by: Yinghai Lu <yinghai@kernel.org> Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Len Brown <lenb@kernel.org> Cc: Andrew Morton <akpm@linux-foundation.org> LKML-Reference: <4A01C46E.8000501@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
@@ -1480,9 +1480,13 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
|
||||
ioapic_write_entry(apic_id, pin, entry);
|
||||
}
|
||||
|
||||
static struct {
|
||||
DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
|
||||
} mp_ioapic_routing[MAX_IO_APICS];
|
||||
|
||||
static void __init setup_IO_APIC_irqs(void)
|
||||
{
|
||||
int apic_id, pin, idx, irq;
|
||||
int apic_id = 0, pin, idx, irq;
|
||||
int notcon = 0;
|
||||
struct irq_desc *desc;
|
||||
struct irq_cfg *cfg;
|
||||
@@ -1490,48 +1494,53 @@ static void __init setup_IO_APIC_irqs(void)
|
||||
|
||||
apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
|
||||
|
||||
for (apic_id = 0; apic_id < nr_ioapics; apic_id++) {
|
||||
for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
|
||||
#ifdef CONFIG_ACPI
|
||||
if (!acpi_disabled && acpi_ioapic) {
|
||||
apic_id = mp_find_ioapic(0);
|
||||
if (apic_id < 0)
|
||||
apic_id = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
idx = find_irq_entry(apic_id, pin, mp_INT);
|
||||
if (idx == -1) {
|
||||
if (!notcon) {
|
||||
notcon = 1;
|
||||
apic_printk(APIC_VERBOSE,
|
||||
KERN_DEBUG " %d-%d",
|
||||
mp_ioapics[apic_id].apicid, pin);
|
||||
} else
|
||||
apic_printk(APIC_VERBOSE, " %d-%d",
|
||||
mp_ioapics[apic_id].apicid, pin);
|
||||
continue;
|
||||
}
|
||||
if (notcon) {
|
||||
for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
|
||||
idx = find_irq_entry(apic_id, pin, mp_INT);
|
||||
if (idx == -1) {
|
||||
if (!notcon) {
|
||||
notcon = 1;
|
||||
apic_printk(APIC_VERBOSE,
|
||||
" (apicid-pin) not connected\n");
|
||||
notcon = 0;
|
||||
}
|
||||
|
||||
irq = pin_2_irq(idx, apic_id, pin);
|
||||
|
||||
/*
|
||||
* Skip the timer IRQ if there's a quirk handler
|
||||
* installed and if it returns 1:
|
||||
*/
|
||||
if (apic->multi_timer_check &&
|
||||
apic->multi_timer_check(apic_id, irq))
|
||||
continue;
|
||||
|
||||
desc = irq_to_desc_alloc_node(irq, node);
|
||||
if (!desc) {
|
||||
printk(KERN_INFO "can not get irq_desc for %d\n", irq);
|
||||
continue;
|
||||
}
|
||||
cfg = desc->chip_data;
|
||||
add_pin_to_irq_node(cfg, node, apic_id, pin);
|
||||
|
||||
setup_IO_APIC_irq(apic_id, pin, irq, desc,
|
||||
irq_trigger(idx), irq_polarity(idx));
|
||||
KERN_DEBUG " %d-%d",
|
||||
mp_ioapics[apic_id].apicid, pin);
|
||||
} else
|
||||
apic_printk(APIC_VERBOSE, " %d-%d",
|
||||
mp_ioapics[apic_id].apicid, pin);
|
||||
continue;
|
||||
}
|
||||
if (notcon) {
|
||||
apic_printk(APIC_VERBOSE,
|
||||
" (apicid-pin) not connected\n");
|
||||
notcon = 0;
|
||||
}
|
||||
|
||||
irq = pin_2_irq(idx, apic_id, pin);
|
||||
|
||||
/*
|
||||
* Skip the timer IRQ if there's a quirk handler
|
||||
* installed and if it returns 1:
|
||||
*/
|
||||
if (apic->multi_timer_check &&
|
||||
apic->multi_timer_check(apic_id, irq))
|
||||
continue;
|
||||
|
||||
desc = irq_to_desc_alloc_node(irq, node);
|
||||
if (!desc) {
|
||||
printk(KERN_INFO "can not get irq_desc for %d\n", irq);
|
||||
continue;
|
||||
}
|
||||
cfg = desc->chip_data;
|
||||
add_pin_to_irq_node(cfg, node, apic_id, pin);
|
||||
set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
|
||||
setup_IO_APIC_irq(apic_id, pin, irq, desc,
|
||||
irq_trigger(idx), irq_polarity(idx));
|
||||
}
|
||||
|
||||
if (notcon)
|
||||
@@ -3876,10 +3885,6 @@ static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, in
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct {
|
||||
DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
|
||||
} mp_ioapic_routing[MAX_IO_APICS];
|
||||
|
||||
int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
|
||||
int triggering, int polarity)
|
||||
{
|
||||
@@ -4023,51 +4028,44 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
|
||||
#ifdef CONFIG_SMP
|
||||
void __init setup_ioapic_dest(void)
|
||||
{
|
||||
int pin, ioapic, irq, irq_entry;
|
||||
int pin, ioapic = 0, irq, irq_entry;
|
||||
struct irq_desc *desc;
|
||||
struct irq_cfg *cfg;
|
||||
const struct cpumask *mask;
|
||||
|
||||
if (skip_ioapic_setup == 1)
|
||||
return;
|
||||
|
||||
for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
|
||||
for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
|
||||
irq_entry = find_irq_entry(ioapic, pin, mp_INT);
|
||||
if (irq_entry == -1)
|
||||
continue;
|
||||
irq = pin_2_irq(irq_entry, ioapic, pin);
|
||||
|
||||
/* setup_IO_APIC_irqs could fail to get vector for some device
|
||||
* when you have too many devices, because at that time only boot
|
||||
* cpu is online.
|
||||
*/
|
||||
desc = irq_to_desc(irq);
|
||||
cfg = desc->chip_data;
|
||||
if (!cfg->vector) {
|
||||
setup_IO_APIC_irq(ioapic, pin, irq, desc,
|
||||
irq_trigger(irq_entry),
|
||||
irq_polarity(irq_entry));
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Honour affinities which have been set in early boot
|
||||
*/
|
||||
if (desc->status &
|
||||
(IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
|
||||
mask = desc->affinity;
|
||||
else
|
||||
mask = apic->target_cpus();
|
||||
|
||||
if (intr_remapping_enabled)
|
||||
set_ir_ioapic_affinity_irq_desc(desc, mask);
|
||||
else
|
||||
set_ioapic_affinity_irq_desc(desc, mask);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
if (!acpi_disabled && acpi_ioapic) {
|
||||
ioapic = mp_find_ioapic(0);
|
||||
if (ioapic < 0)
|
||||
ioapic = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
|
||||
irq_entry = find_irq_entry(ioapic, pin, mp_INT);
|
||||
if (irq_entry == -1)
|
||||
continue;
|
||||
irq = pin_2_irq(irq_entry, ioapic, pin);
|
||||
|
||||
desc = irq_to_desc(irq);
|
||||
|
||||
/*
|
||||
* Honour affinities which have been set in early boot
|
||||
*/
|
||||
if (desc->status &
|
||||
(IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
|
||||
mask = desc->affinity;
|
||||
else
|
||||
mask = apic->target_cpus();
|
||||
|
||||
if (intr_remapping_enabled)
|
||||
set_ir_ioapic_affinity_irq_desc(desc, mask);
|
||||
else
|
||||
set_ioapic_affinity_irq_desc(desc, mask);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user