x86/apic: Add irq_data argument to apic->cpu_mask_to_apicid()
authorThomas Gleixner <tglx@linutronix.de>
Mon, 19 Jun 2017 23:37:44 +0000 (01:37 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 22 Jun 2017 16:21:22 +0000 (18:21 +0200)
The decision to which CPUs an interrupt is effectively routed happens in
the various apic->cpu_mask_to_apicid() implementations

To support effective affinity masks this information needs to be updated in
irq_data. Add a pointer to irq_data to the callbacks and feed it through
the call chain.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Keith Busch <keith.busch@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Christoph Hellwig <hch@lst.de>
Link: http://lkml.kernel.org/r/20170619235446.720739075@linutronix.de
arch/x86/include/asm/apic.h
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/vector.c
arch/x86/kernel/apic/x2apic_cluster.c
arch/x86/kernel/apic/x2apic_uv_x.c

index 3e64e99edc362adc9d8b58666e3053a09498a358..5f01671c68f267ccc3b3aedd518134453162733a 100644 (file)
@@ -252,6 +252,8 @@ static inline int x2apic_enabled(void) { return 0; }
 #define        x2apic_supported()      (0)
 #endif /* !CONFIG_X86_X2APIC */
 
+struct irq_data;
+
 /*
  * Copyright 2004 James Cleverdon, IBM.
  * Subject to the GNU Public License, v.2
@@ -297,6 +299,7 @@ struct apic {
        unsigned long (*set_apic_id)(unsigned int id);
 
        int (*cpu_mask_to_apicid)(const struct cpumask *cpumask,
+                                 struct irq_data *irqdata,
                                  unsigned int *apicid);
 
        /* ipi */
@@ -540,8 +543,10 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)
 #endif
 
 extern int flat_cpu_mask_to_apicid(const struct cpumask *cpumask,
+                                  struct irq_data *irqdata,
                                   unsigned int *apicid);
 extern int default_cpu_mask_to_apicid(const struct cpumask *cpumask,
+                                     struct irq_data *irqdata,
                                      unsigned int *apicid);
 
 static inline void
index 169dd422dc30c83f125304100038b08bc7266eab..14e5a47192b778f0be2e82e4f454355acbcc343a 100644 (file)
@@ -2201,7 +2201,9 @@ void default_init_apic_ldr(void)
        apic_write(APIC_LDR, val);
 }
 
-int default_cpu_mask_to_apicid(const struct cpumask *mask, unsigned int *apicid)
+int default_cpu_mask_to_apicid(const struct cpumask *mask,
+                              struct irq_data *irqdata,
+                              unsigned int *apicid)
 {
        unsigned int cpu = cpumask_first(mask);
 
@@ -2211,7 +2213,10 @@ int default_cpu_mask_to_apicid(const struct cpumask *mask, unsigned int *apicid)
        return 0;
 }
 
-int flat_cpu_mask_to_apicid(const struct cpumask *mask, unsigned int *apicid)
+int flat_cpu_mask_to_apicid(const struct cpumask *mask,
+                           struct irq_data *irqdata,
+                           unsigned int *apicid)
+
 {
        unsigned long cpu_mask = cpumask_bits(mask)[0] & APIC_ALL_CPUS;
 
index 1f57f5a08c44d66228b1876ae02adc624f963657..b270a76ee6404684e7d61700f3740d8d71264923 100644 (file)
@@ -103,7 +103,8 @@ static void free_apic_chip_data(struct apic_chip_data *data)
 }
 
 static int __assign_irq_vector(int irq, struct apic_chip_data *d,
-                              const struct cpumask *mask)
+                              const struct cpumask *mask,
+                              struct irq_data *irqdata)
 {
        /*
         * NOTE! The local APIC isn't very good at handling
@@ -226,32 +227,35 @@ success:
         * cpus masked out.
         */
        cpumask_and(vector_searchmask, vector_searchmask, mask);
-       BUG_ON(apic->cpu_mask_to_apicid(vector_searchmask, &d->cfg.dest_apicid));
+       BUG_ON(apic->cpu_mask_to_apicid(vector_searchmask, irqdata,
+                                       &d->cfg.dest_apicid));
        return 0;
 }
 
 static int assign_irq_vector(int irq, struct apic_chip_data *data,
-                            const struct cpumask *mask)
+                            const struct cpumask *mask,
+                            struct irq_data *irqdata)
 {
        int err;
        unsigned long flags;
 
        raw_spin_lock_irqsave(&vector_lock, flags);
-       err = __assign_irq_vector(irq, data, mask);
+       err = __assign_irq_vector(irq, data, mask, irqdata);
        raw_spin_unlock_irqrestore(&vector_lock, flags);
        return err;
 }
 
 static int assign_irq_vector_policy(int irq, int node,
                                    struct apic_chip_data *data,
-                                   struct irq_alloc_info *info)
+                                   struct irq_alloc_info *info,
+                                   struct irq_data *irqdata)
 {
        if (info && info->mask)
-               return assign_irq_vector(irq, data, info->mask);
+               return assign_irq_vector(irq, data, info->mask, irqdata);
        if (node != NUMA_NO_NODE &&
-           assign_irq_vector(irq, data, cpumask_of_node(node)) == 0)
+           assign_irq_vector(irq, data, cpumask_of_node(node), irqdata) == 0)
                return 0;
-       return assign_irq_vector(irq, data, apic->target_cpus());
+       return assign_irq_vector(irq, data, apic->target_cpus(), irqdata);
 }
 
 static void clear_irq_vector(int irq, struct apic_chip_data *data)
@@ -363,7 +367,8 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq,
                irq_data->chip = &lapic_controller;
                irq_data->chip_data = data;
                irq_data->hwirq = virq + i;
-               err = assign_irq_vector_policy(virq + i, node, data, info);
+               err = assign_irq_vector_policy(virq + i, node, data, info,
+                                              irq_data);
                if (err)
                        goto error;
        }
@@ -537,7 +542,7 @@ static int apic_set_affinity(struct irq_data *irq_data,
        if (!cpumask_intersects(dest, cpu_online_mask))
                return -EINVAL;
 
-       err = assign_irq_vector(irq, data, dest);
+       err = assign_irq_vector(irq, data, dest, irq_data);
        return err ? err : IRQ_SET_MASK_OK;
 }
 
index 61474259bf3f9ac25694044f9ded643ab781716e..305031e0a228bca04b88e835f58a0de9c403a990 100644 (file)
@@ -104,7 +104,8 @@ static void x2apic_send_IPI_all(int vector)
 }
 
 static int
-x2apic_cpu_mask_to_apicid(const struct cpumask *mask, unsigned int *apicid)
+x2apic_cpu_mask_to_apicid(const struct cpumask *mask, struct irq_data *irqdata,
+                         unsigned int *apicid)
 {
        unsigned int cpu;
        u32 dest = 0;
index ad0223f013f6bb2b346077221bbf9f8f5a46b1b4..0d57bb9079c998173f31bc2f4b73032caf23331b 100644 (file)
@@ -526,9 +526,10 @@ static void uv_init_apic_ldr(void)
 }
 
 static int
-uv_cpu_mask_to_apicid(const struct cpumask *mask, unsigned int *apicid)
+uv_cpu_mask_to_apicid(const struct cpumask *mask, struct irq_data *irqdata,
+                     unsigned int *apicid)
 {
-       int ret = default_cpu_mask_to_apicid(mask, apicid);
+       int ret = default_cpu_mask_to_apicid(mask, irqdata, apicid);
 
        if (!ret)
                *apicid |= uv_apicid_hibits;