Commit 4ef76eb6 authored by Thomas Gleixner's avatar Thomas Gleixner

x86/apic: Get rid of the legacy irq data storage

Now that the legacy PIC takeover by the IOAPIC is marked accordingly the
early boot allocation of APIC data is not longer necessary. Use the regular
allocation mechansim as it is used by non legacy interrupts and fill in the
known information (vector and affinity) so the allocator reuses the vector,
This is important as the timer check might move the timer interrupt 0 back
to the PIC in case the delivery through the IOAPIC fails.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarJuergen Gross <jgross@suse.com>
Tested-by: default avatarYu Chen <yu.c.chen@intel.com>
Acked-by: default avatarJuergen Gross <jgross@suse.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Alok Kataria <akataria@vmware.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Rui Zhang <rui.zhang@intel.com>
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Len Brown <lenb@kernel.org>
Link: https://lkml.kernel.org/r/20170913213154.780521549@linutronix.de
parent 3534be05
...@@ -36,9 +36,6 @@ EXPORT_SYMBOL_GPL(x86_vector_domain); ...@@ -36,9 +36,6 @@ EXPORT_SYMBOL_GPL(x86_vector_domain);
static DEFINE_RAW_SPINLOCK(vector_lock); static DEFINE_RAW_SPINLOCK(vector_lock);
static cpumask_var_t vector_cpumask, vector_searchmask, searched_cpumask; static cpumask_var_t vector_cpumask, vector_searchmask, searched_cpumask;
static struct irq_chip lapic_controller; static struct irq_chip lapic_controller;
#ifdef CONFIG_X86_IO_APIC
static struct apic_chip_data *legacy_irq_data[NR_IRQS_LEGACY];
#endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static DEFINE_PER_CPU(struct hlist_head, cleanup_list); static DEFINE_PER_CPU(struct hlist_head, cleanup_list);
#endif #endif
...@@ -317,10 +314,6 @@ static void x86_vector_free_irqs(struct irq_domain *domain, ...@@ -317,10 +314,6 @@ static void x86_vector_free_irqs(struct irq_domain *domain,
irq_domain_reset_irq_data(irqd); irq_domain_reset_irq_data(irqd);
raw_spin_unlock_irqrestore(&vector_lock, flags); raw_spin_unlock_irqrestore(&vector_lock, flags);
free_apic_chip_data(apicd); free_apic_chip_data(apicd);
#ifdef CONFIG_X86_IO_APIC
if (virq + i < nr_legacy_irqs())
legacy_irq_data[virq + i] = NULL;
#endif
} }
} }
} }
...@@ -344,12 +337,8 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq, ...@@ -344,12 +337,8 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq,
irqd = irq_domain_get_irq_data(domain, virq + i); irqd = irq_domain_get_irq_data(domain, virq + i);
BUG_ON(!irqd); BUG_ON(!irqd);
node = irq_data_get_node(irqd); node = irq_data_get_node(irqd);
#ifdef CONFIG_X86_IO_APIC WARN_ON_ONCE(irqd->chip_data);
if (virq + i < nr_legacy_irqs() && legacy_irq_data[virq + i]) apicd = alloc_apic_chip_data(node);
apicd = legacy_irq_data[virq + i];
else
#endif
apicd = alloc_apic_chip_data(node);
if (!apicd) { if (!apicd) {
err = -ENOMEM; err = -ENOMEM;
goto error; goto error;
...@@ -359,6 +348,17 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq, ...@@ -359,6 +348,17 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq,
irqd->chip_data = apicd; irqd->chip_data = apicd;
irqd->hwirq = virq + i; irqd->hwirq = virq + i;
irqd_set_single_target(irqd); irqd_set_single_target(irqd);
/*
* Make sure, that the legacy to IOAPIC transition stays on
* the same vector. This is required for check_timer() to
* work correctly as it might switch back to legacy mode.
*/
if (info->flags & X86_IRQ_ALLOC_LEGACY) {
apicd->cfg.vector = ISA_IRQ_VECTOR(virq + i);
apicd->cpu = 0;
cpumask_copy(apicd->domain, cpumask_of(0));
}
err = assign_irq_vector_policy(virq + i, node, apicd, info, err = assign_irq_vector_policy(virq + i, node, apicd, info,
irqd); irqd);
if (err) if (err)
...@@ -404,36 +404,10 @@ int __init arch_probe_nr_irqs(void) ...@@ -404,36 +404,10 @@ int __init arch_probe_nr_irqs(void)
return legacy_pic->probe(); return legacy_pic->probe();
} }
#ifdef CONFIG_X86_IO_APIC
static void __init init_legacy_irqs(void)
{
int i, node = cpu_to_node(0);
struct apic_chip_data *apicd;
/*
* For legacy IRQ's, start with assigning irq0 to irq15 to
* ISA_IRQ_VECTOR(i) for all cpu's.
*/
for (i = 0; i < nr_legacy_irqs(); i++) {
apicd = legacy_irq_data[i] = alloc_apic_chip_data(node);
BUG_ON(!apicd);
apicd->cfg.vector = ISA_IRQ_VECTOR(i);
cpumask_copy(apicd->domain, cpumask_of(0));
apicd->cpu = 0;
irq_set_chip_data(i, apicd);
}
}
#else
static inline void init_legacy_irqs(void) { }
#endif
int __init arch_early_irq_init(void) int __init arch_early_irq_init(void)
{ {
struct fwnode_handle *fn; struct fwnode_handle *fn;
init_legacy_irqs();
fn = irq_domain_alloc_named_fwnode("VECTOR"); fn = irq_domain_alloc_named_fwnode("VECTOR");
BUG_ON(!fn); BUG_ON(!fn);
x86_vector_domain = irq_domain_create_tree(fn, &x86_vector_domain_ops, x86_vector_domain = irq_domain_create_tree(fn, &x86_vector_domain_ops,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment