OSDN Git Service

x86/io_apic: Reevaluate vector configuration on activate()
authorThomas Gleixner <tglx@linutronix.de>
Wed, 13 Sep 2017 21:29:49 +0000 (23:29 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 25 Sep 2017 18:52:01 +0000 (20:52 +0200)
With the upcoming reservation/management scheme, early activation will
assign a special vector. The final activation at request_irq() assigns a
real vector, which needs to be updated in the ioapic.

Split out the reconfiguration code in set_affinity and use it for
reactivation.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Juergen Gross <jgross@suse.com>
Tested-by: Yu Chen <yu.c.chen@intel.com>
Acked-by: Juergen 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/20170913213156.025232175@linutronix.de
arch/x86/kernel/apic/io_apic.c

index a4b0c60..18c6a48 100644 (file)
@@ -1862,26 +1862,36 @@ static void ioapic_ir_ack_level(struct irq_data *irq_data)
        eoi_ioapic_pin(data->entry.vector, data);
 }
 
+static void ioapic_configure_entry(struct irq_data *irqd)
+{
+       struct mp_chip_data *mpd = irqd->chip_data;
+       struct irq_cfg *cfg = irqd_cfg(irqd);
+       struct irq_pin_list *entry;
+
+       /*
+        * Only update when the parent is the vector domain, don't touch it
+        * if the parent is the remapping domain. Check the installed
+        * ioapic chip to verify that.
+        */
+       if (irqd->chip == &ioapic_chip) {
+               mpd->entry.dest = cfg->dest_apicid;
+               mpd->entry.vector = cfg->vector;
+       }
+       for_each_irq_pin(entry, mpd->irq_2_pin)
+               __ioapic_write_entry(entry->apic, entry->pin, mpd->entry);
+}
+
 static int ioapic_set_affinity(struct irq_data *irq_data,
                               const struct cpumask *mask, bool force)
 {
        struct irq_data *parent = irq_data->parent_data;
-       struct mp_chip_data *data = irq_data->chip_data;
-       struct irq_pin_list *entry;
-       struct irq_cfg *cfg;
        unsigned long flags;
        int ret;
 
        ret = parent->chip->irq_set_affinity(parent, mask, force);
        raw_spin_lock_irqsave(&ioapic_lock, flags);
-       if (ret >= 0 && ret != IRQ_SET_MASK_OK_DONE) {
-               cfg = irqd_cfg(irq_data);
-               data->entry.dest = cfg->dest_apicid;
-               data->entry.vector = cfg->vector;
-               for_each_irq_pin(entry, data->irq_2_pin)
-                       __ioapic_write_entry(entry->apic, entry->pin,
-                                            data->entry);
-       }
+       if (ret >= 0 && ret != IRQ_SET_MASK_OK_DONE)
+               ioapic_configure_entry(irq_data);
        raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
        return ret;
@@ -2980,12 +2990,9 @@ int mp_irqdomain_activate(struct irq_domain *domain,
                          struct irq_data *irq_data, bool early)
 {
        unsigned long flags;
-       struct irq_pin_list *entry;
-       struct mp_chip_data *data = irq_data->chip_data;
 
        raw_spin_lock_irqsave(&ioapic_lock, flags);
-       for_each_irq_pin(entry, data->irq_2_pin)
-               __ioapic_write_entry(entry->apic, entry->pin, data->entry);
+       ioapic_configure_entry(irq_data);
        raw_spin_unlock_irqrestore(&ioapic_lock, flags);
        return 0;
 }