fixup_irqs() calls chip->set_irq_affinity which eventually calls
__assign_irq_vector().  Errors are not propogated back from this function call
and this results in silent irq relocation failures.  This patch fixes this
issue and prints out a warning if there is a relocation failure.

Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: "H. Peter Anvin" <h...@zytor.com>
Cc: x...@kernel.org
Cc: Rui Wang <rui.y.w...@intel.com>
Cc: Liu Ping Fan <kernelf...@gmail.com>
Cc: Bjorn Helgaas <bhelg...@google.com>
Cc: Yoshihiro YUNOMAE <yoshihiro.yunomae...@hitachi.com>
Cc: Lv Zheng <lv.zh...@intel.com>
Cc: Seiji Aguchi <seiji.agu...@hds.com>
Cc: Yang Zhang <yang.z.zh...@intel.com>
Cc: Andi Kleen <a...@linux.intel.com>
Cc: "Steven Rostedt (Red Hat)" <rost...@goodmis.org>
Cc: Li Fei <fei...@intel.com>
Cc: gong.c...@linux.intel.com
Signed-off-by: Prarit Bhargava <pra...@redhat.com>
---
 arch/x86/kernel/apic/io_apic.c |   28 ++++++++++++++++++----------
 arch/x86/kernel/irq.c          |    9 +++++++--
 2 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 6ad4658..b4b21db 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2312,7 +2312,7 @@ int __ioapic_set_affinity(struct irq_data *data, const 
struct cpumask *mask,
        int err;
 
        if (!config_enabled(CONFIG_SMP))
-               return -1;
+               return -EPERM;
 
        if (!cpumask_intersects(mask, cpu_online_mask))
                return -EINVAL;
@@ -2343,7 +2343,7 @@ int native_ioapic_set_affinity(struct irq_data *data,
        int ret;
 
        if (!config_enabled(CONFIG_SMP))
-               return -1;
+               return -EPERM;
 
        raw_spin_lock_irqsave(&ioapic_lock, flags);
        ret = __ioapic_set_affinity(data, mask, &dest);
@@ -3075,9 +3075,11 @@ msi_set_affinity(struct irq_data *data, const struct 
cpumask *mask, bool force)
        struct irq_cfg *cfg = data->chip_data;
        struct msi_msg msg;
        unsigned int dest;
+       int ret;
 
-       if (__ioapic_set_affinity(data, mask, &dest))
-               return -1;
+       ret = __ioapic_set_affinity(data, mask, &dest);
+       if (ret)
+               return ret;
 
        __get_cached_msi_msg(data->msi_desc, &msg);
 
@@ -3177,9 +3179,11 @@ dmar_msi_set_affinity(struct irq_data *data, const 
struct cpumask *mask,
        struct irq_cfg *cfg = data->chip_data;
        unsigned int dest, irq = data->irq;
        struct msi_msg msg;
+       int ret;
 
-       if (__ioapic_set_affinity(data, mask, &dest))
-               return -1;
+       ret = __ioapic_set_affinity(data, mask, &dest);
+       if (ret)
+               return ret;
 
        dmar_msi_read(irq, &msg);
 
@@ -3226,9 +3230,11 @@ static int hpet_msi_set_affinity(struct irq_data *data,
        struct irq_cfg *cfg = data->chip_data;
        struct msi_msg msg;
        unsigned int dest;
+       int ret;
 
-       if (__ioapic_set_affinity(data, mask, &dest))
-               return -1;
+       ret = __ioapic_set_affinity(data, mask, &dest);
+       if (ret)
+               return ret;
 
        hpet_msi_read(data->handler_data, &msg);
 
@@ -3295,9 +3301,11 @@ ht_set_affinity(struct irq_data *data, const struct 
cpumask *mask, bool force)
 {
        struct irq_cfg *cfg = data->chip_data;
        unsigned int dest;
+       int ret;
 
-       if (__ioapic_set_affinity(data, mask, &dest))
-               return -1;
+       ret = __ioapic_set_affinity(data, mask, &dest);
+       if (ret)
+               return ret;
 
        target_ht_irq(data->irq, dest, cfg->vector);
        return IRQ_SET_MASK_OK_NOCOPY;
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index d99f31d..55fab61 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -351,6 +351,7 @@ void fixup_irqs(void)
        struct irq_desc *desc;
        struct irq_data *data;
        struct irq_chip *chip;
+       int ret;
 
        for_each_irq_desc(irq, desc) {
                int break_affinity = 0;
@@ -389,8 +390,12 @@ void fixup_irqs(void)
                if (!irqd_can_move_in_process_context(data) && chip->irq_mask)
                        chip->irq_mask(data);
 
-               if (chip->irq_set_affinity)
-                       chip->irq_set_affinity(data, affinity, true);
+               if (chip->irq_set_affinity) {
+                       ret = chip->irq_set_affinity(data, affinity, true);
+                       WARN(ret == -ENOSPC,
+                            "IRQ %d set affinity failed with %d.  The device 
assigned to this IRQ is unstable.\n",
+                            irq, ret);
+               }
                else if (!(warned++))
                        set_affinity = 0;
 
-- 
1.7.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to