Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 312421
b: refs/heads/master
c: ff16432
h: refs/heads/master
i:
  312419: 657448b
v: v3
  • Loading branch information
Alexander Gordeev authored and Ingo Molnar committed Jun 8, 2012
1 parent 9fd127e commit 5906ce4
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 106 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8637e38aff14d048b649075114023023a2e80fba
refs/heads/master: ff164324123c0fe181d8de7dadcc7b3fbe25f2cf
44 changes: 31 additions & 13 deletions trunk/arch/x86/include/asm/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,11 @@ struct apic {
unsigned long (*set_apic_id)(unsigned int id);
unsigned long apic_id_mask;

unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask);
unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
const struct cpumask *andmask);
int (*cpu_mask_to_apicid)(const struct cpumask *cpumask,
unsigned int *apicid);
int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
const struct cpumask *andmask,
unsigned int *apicid);

/* ipi */
void (*send_IPI_mask)(const struct cpumask *mask, int vector);
Expand Down Expand Up @@ -591,29 +593,45 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)

#endif

static inline unsigned int
flat_cpu_mask_to_apicid(const struct cpumask *cpumask)
static inline int
__flat_cpu_mask_to_apicid(unsigned long cpu_mask, unsigned int *apicid)
{
return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS;
cpu_mask &= APIC_ALL_CPUS;
if (likely(cpu_mask)) {
*apicid = (unsigned int)cpu_mask;
return 0;
} else {
return -EINVAL;
}
}

static inline unsigned int
static inline int
flat_cpu_mask_to_apicid(const struct cpumask *cpumask,
unsigned int *apicid)
{
return __flat_cpu_mask_to_apicid(cpumask_bits(cpumask)[0], apicid);
}

static inline int
flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
const struct cpumask *andmask)
const struct cpumask *andmask,
unsigned int *apicid)
{
unsigned long mask1 = cpumask_bits(cpumask)[0];
unsigned long mask2 = cpumask_bits(andmask)[0];
unsigned long mask3 = cpumask_bits(cpu_online_mask)[0];

return (unsigned int)(mask1 & mask2 & mask3);
return __flat_cpu_mask_to_apicid(mask1 & mask2 & mask3, apicid);
}

extern unsigned int
default_cpu_mask_to_apicid(const struct cpumask *cpumask);
extern int
default_cpu_mask_to_apicid(const struct cpumask *cpumask,
unsigned int *apicid);

extern unsigned int
extern int
default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
const struct cpumask *andmask);
const struct cpumask *andmask,
unsigned int *apicid);

static inline bool
flat_vector_allocation_domain(int cpu, struct cpumask *retmask)
Expand Down
33 changes: 18 additions & 15 deletions trunk/arch/x86/kernel/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -2123,32 +2123,35 @@ void default_init_apic_ldr(void)
apic_write(APIC_LDR, val);
}

unsigned int default_cpu_mask_to_apicid(const struct cpumask *cpumask)
static inline int __default_cpu_to_apicid(int cpu, unsigned int *apicid)
{
int cpu;

/*
* We're using fixed IRQ delivery, can only return one phys APIC ID.
* May as well be the first.
*/
cpu = cpumask_first(cpumask);
if (likely((unsigned)cpu < nr_cpu_ids))
return per_cpu(x86_cpu_to_apicid, cpu);
if (likely((unsigned int)cpu < nr_cpu_ids)) {
*apicid = per_cpu(x86_cpu_to_apicid, cpu);
return 0;
} else {
return -EINVAL;
}
}

return BAD_APICID;
int default_cpu_mask_to_apicid(const struct cpumask *cpumask,
unsigned int *apicid)
{
int cpu = cpumask_first(cpumask);
return __default_cpu_to_apicid(cpu, apicid);
}

unsigned int
default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
const struct cpumask *andmask)
int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
const struct cpumask *andmask,
unsigned int *apicid)
{
int cpu;

for_each_cpu_and(cpu, cpumask, andmask) {
if (cpumask_test_cpu(cpu, cpu_online_mask))
break;
}
return per_cpu(x86_cpu_to_apicid, cpu);

return __default_cpu_to_apicid(cpu, apicid);
}

/*
Expand Down
21 changes: 12 additions & 9 deletions trunk/arch/x86/kernel/apic/es7000_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,8 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
return 1;
}

static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask)
static int
es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id)
{
unsigned int round = 0;
int cpu, uninitialized_var(apicid);
Expand All @@ -539,31 +540,33 @@ static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask)
if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
WARN(1, "Not a valid mask!");

return BAD_APICID;
return -EINVAL;
}
apicid = new_apicid;
round++;
}
return apicid;
*dest_id = apicid;
return 0;
}

static unsigned int
static int
es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
const struct cpumask *andmask)
const struct cpumask *andmask,
unsigned int *apicid)
{
int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0);
*apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0);
cpumask_var_t cpumask;

if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
return apicid;
return 0;

cpumask_and(cpumask, inmask, andmask);
cpumask_and(cpumask, cpumask, cpu_online_mask);
apicid = es7000_cpu_mask_to_apicid(cpumask);
es7000_cpu_mask_to_apicid(cpumask, apicid);

free_cpumask_var(cpumask);

return apicid;
return 0;
}

static int es7000_phys_pkg_id(int cpuid_apic, int index_msb)
Expand Down
88 changes: 57 additions & 31 deletions trunk/arch/x86/kernel/apic/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1359,7 +1359,14 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
if (assign_irq_vector(irq, cfg, apic->target_cpus()))
return;

dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
if (apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus(),
&dest)) {
pr_warn("Failed to obtain apicid for ioapic %d, pin %d\n",
mpc_ioapic_id(attr->ioapic), attr->ioapic_pin);
__clear_irq_vector(irq, cfg);

return;
}

apic_printk(APIC_VERBOSE,KERN_DEBUG
"IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> "
Expand Down Expand Up @@ -1474,6 +1481,7 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx,
unsigned int pin, int vector)
{
struct IO_APIC_route_entry entry;
unsigned int dest;

if (irq_remapping_enabled)
return;
Expand All @@ -1484,9 +1492,12 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx,
* We use logical delivery to get the timer IRQ
* to the first CPU.
*/
if (unlikely(apic->cpu_mask_to_apicid(apic->target_cpus(), &dest)))
dest = BAD_APICID;

entry.dest_mode = apic->irq_dest_mode;
entry.mask = 0; /* don't mask IRQ for edge */
entry.dest = apic->cpu_mask_to_apicid(apic->target_cpus());
entry.dest = dest;
entry.delivery_mode = apic->irq_delivery_mode;
entry.polarity = 0;
entry.trigger = 0;
Expand Down Expand Up @@ -2245,16 +2256,25 @@ int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
unsigned int *dest_id)
{
struct irq_cfg *cfg = data->chip_data;
unsigned int irq = data->irq;
int err;

if (!cpumask_intersects(mask, cpu_online_mask))
return -1;
return -EINVAL;

if (assign_irq_vector(data->irq, data->chip_data, mask))
return -1;
err = assign_irq_vector(irq, cfg, mask);
if (err)
return err;

err = apic->cpu_mask_to_apicid_and(mask, cfg->domain, dest_id);
if (err) {
if (assign_irq_vector(irq, cfg, data->affinity))
pr_err("Failed to recover vector for irq %d\n", irq);
return err;
}

cpumask_copy(data->affinity, mask);

*dest_id = apic->cpu_mask_to_apicid_and(mask, cfg->domain);
return 0;
}

Expand Down Expand Up @@ -3040,7 +3060,10 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
if (err)
return err;

dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
err = apic->cpu_mask_to_apicid_and(cfg->domain,
apic->target_cpus(), &dest);
if (err)
return err;

if (irq_remapped(cfg)) {
compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id);
Expand Down Expand Up @@ -3361,43 +3384,46 @@ static struct irq_chip ht_irq_chip = {
int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
{
struct irq_cfg *cfg;
struct ht_irq_msg msg;
unsigned dest;
int err;

if (disable_apic)
return -ENXIO;

cfg = irq_cfg(irq);
err = assign_irq_vector(irq, cfg, apic->target_cpus());
if (!err) {
struct ht_irq_msg msg;
unsigned dest;
if (err)
return err;

dest = apic->cpu_mask_to_apicid_and(cfg->domain,
apic->target_cpus());
err = apic->cpu_mask_to_apicid_and(cfg->domain,
apic->target_cpus(), &dest);
if (err)
return err;

msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);
msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);

msg.address_lo =
HT_IRQ_LOW_BASE |
HT_IRQ_LOW_DEST_ID(dest) |
HT_IRQ_LOW_VECTOR(cfg->vector) |
((apic->irq_dest_mode == 0) ?
HT_IRQ_LOW_DM_PHYSICAL :
HT_IRQ_LOW_DM_LOGICAL) |
HT_IRQ_LOW_RQEOI_EDGE |
((apic->irq_delivery_mode != dest_LowestPrio) ?
HT_IRQ_LOW_MT_FIXED :
HT_IRQ_LOW_MT_ARBITRATED) |
HT_IRQ_LOW_IRQ_MASKED;
msg.address_lo =
HT_IRQ_LOW_BASE |
HT_IRQ_LOW_DEST_ID(dest) |
HT_IRQ_LOW_VECTOR(cfg->vector) |
((apic->irq_dest_mode == 0) ?
HT_IRQ_LOW_DM_PHYSICAL :
HT_IRQ_LOW_DM_LOGICAL) |
HT_IRQ_LOW_RQEOI_EDGE |
((apic->irq_delivery_mode != dest_LowestPrio) ?
HT_IRQ_LOW_MT_FIXED :
HT_IRQ_LOW_MT_ARBITRATED) |
HT_IRQ_LOW_IRQ_MASKED;

write_ht_irq_msg(irq, &msg);
write_ht_irq_msg(irq, &msg);

irq_set_chip_and_handler_name(irq, &ht_irq_chip,
handle_edge_irq, "edge");
irq_set_chip_and_handler_name(irq, &ht_irq_chip,
handle_edge_irq, "edge");

dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq);
}
return err;
dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq);

return 0;
}
#endif /* CONFIG_HT_IRQ */

Expand Down
14 changes: 9 additions & 5 deletions trunk/arch/x86/kernel/apic/numaq_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,16 +406,20 @@ static inline int numaq_check_phys_apicid_present(int phys_apicid)
* We use physical apicids here, not logical, so just return the default
* physical broadcast to stop people from breaking us
*/
static unsigned int numaq_cpu_mask_to_apicid(const struct cpumask *cpumask)
static int
numaq_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid)
{
return 0x0F;
*apicid = 0x0F;
return 0;
}

static inline unsigned int
static int
numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
const struct cpumask *andmask)
const struct cpumask *andmask,
unsigned int *apicid)
{
return 0x0F;
*apicid = 0x0F;
return 0;
}

/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */
Expand Down
Loading

0 comments on commit 5906ce4

Please sign in to comment.