mirror of https://gitee.com/openkylin/linux.git
x86/apic: Add irq_data argument to apic->cpu_mask_to_apicid()
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
This commit is contained in:
parent
91cd9cb7ee
commit
0e24f7c9f6
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 @@ static int __assign_irq_vector(int irq, struct apic_chip_data *d,
|
|||
* 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue