Commit a5aea3c6 authored by Martin J. Bligh's avatar Martin J. Bligh Committed by Linus Torvalds

[PATCH] Make IRQ balancing work with clustered APICs

Patch from James Cleverdon & John Stultz

The IRQ balancing code currently assumes that the logical apicid is
always '1 << cpu', which is not true for the larger platforms.
We express this as an abstracted macro instead, and move the
cpu_to_logical_apicid definition to subarch, so we can make it exactly
"1 << cpu" for normal machines - maximum speed, minimum change risk.

A couple of things are abstracted from the smp_boot_cpus loop in order
to enable us to use the bios_cpu_apicid array to boot cpus from without
disturbing the code path of current machines.
parent 3bbeca78
...@@ -278,7 +278,7 @@ static inline void balance_irq(int irq) ...@@ -278,7 +278,7 @@ static inline void balance_irq(int irq)
new_cpu = move(entry->cpu, allowed_mask, now, random_number); new_cpu = move(entry->cpu, allowed_mask, now, random_number);
if (entry->cpu != new_cpu) { if (entry->cpu != new_cpu) {
entry->cpu = new_cpu; entry->cpu = new_cpu;
set_ioapic_affinity(irq, 1 << new_cpu); set_ioapic_affinity(irq, cpu_to_logical_apicid(new_cpu));
} }
} }
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <mach_ipi.h> #include <mach_ipi.h>
#include <mach_apic.h>
/* /*
* Some notes on x86 processor bugs affecting SMP operation: * Some notes on x86 processor bugs affecting SMP operation:
......
...@@ -1045,10 +1045,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -1045,10 +1045,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
/* /*
* Don't even attempt to start the boot CPU! * Don't even attempt to start the boot CPU!
*/ */
if (apicid == boot_cpu_apicid) if ((apicid == boot_cpu_apicid) || (apicid == BAD_APICID))
continue; continue;
if (!(phys_cpu_present_map & (1 << bit))) if (!check_apicid_present(bit))
continue; continue;
if (max_cpus <= cpucount+1) if (max_cpus <= cpucount+1)
continue; continue;
......
...@@ -26,6 +26,7 @@ static inline int apic_id_registered(void) ...@@ -26,6 +26,7 @@ static inline int apic_id_registered(void)
#define APIC_BROADCAST_ID (0x0f) #define APIC_BROADCAST_ID (0x0f)
#define check_apicid_used(bitmap, apicid) (0) #define check_apicid_used(bitmap, apicid) (0)
#define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit))
static inline unsigned long calculate_ldr(unsigned long old) static inline unsigned long calculate_ldr(unsigned long old)
{ {
...@@ -79,6 +80,13 @@ static inline unsigned long apicid_to_cpu_present(int phys_apicid) ...@@ -79,6 +80,13 @@ static inline unsigned long apicid_to_cpu_present(int phys_apicid)
return (1ul << phys_apicid); return (1ul << phys_apicid);
} }
extern volatile u8 cpu_2_logical_apicid[];
/* Mapping from cpu number to logical apicid */
static inline int cpu_to_logical_apicid(int cpu)
{
return (int)cpu_2_logical_apicid[cpu];
}
static inline int mpc_apic_id(struct mpc_config_processor *m, int quad) static inline int mpc_apic_id(struct mpc_config_processor *m, int quad)
{ {
printk("Processor #%d %ld:%ld APIC version %d\n", printk("Processor #%d %ld:%ld APIC version %d\n",
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#define APIC_BROADCAST_ID 0x0F #define APIC_BROADCAST_ID 0x0F
#define check_apicid_used(bitmap, apicid) (bitmap & (1 << apicid)) #define check_apicid_used(bitmap, apicid) (bitmap & (1 << apicid))
#define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit))
static inline int apic_id_registered(void) static inline int apic_id_registered(void)
{ {
...@@ -62,6 +63,12 @@ static inline int apicid_to_node(int logical_apicid) ...@@ -62,6 +63,12 @@ static inline int apicid_to_node(int logical_apicid)
return 0; return 0;
} }
/* Mapping from cpu number to logical apicid */
static inline int cpu_to_logical_apicid(int cpu)
{
return 1 << cpu;
}
static inline int cpu_present_to_apicid(int mps_cpu) static inline int cpu_present_to_apicid(int mps_cpu)
{ {
return mps_cpu; return mps_cpu;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#define APIC_BROADCAST_ID 0x0F #define APIC_BROADCAST_ID 0x0F
#define check_apicid_used(bitmap, apicid) ((bitmap) & (1 << (apicid))) #define check_apicid_used(bitmap, apicid) ((bitmap) & (1 << (apicid)))
#define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit))
static inline int apic_id_registered(void) static inline int apic_id_registered(void)
{ {
...@@ -45,6 +46,13 @@ static inline ulong ioapic_phys_id_map(ulong phys_map) ...@@ -45,6 +46,13 @@ static inline ulong ioapic_phys_id_map(ulong phys_map)
return 0xf; return 0xf;
} }
/* Mapping from cpu number to logical apicid */
extern volatile u8 cpu_2_logical_apicid[];
static inline int cpu_to_logical_apicid(int cpu)
{
return (int)cpu_2_logical_apicid[cpu];
}
static inline int cpu_present_to_apicid(int mps_cpu) static inline int cpu_present_to_apicid(int mps_cpu)
{ {
return ( ((mps_cpu/4)*16) + (1<<(mps_cpu%4)) ); return ( ((mps_cpu/4)*16) + (1<<(mps_cpu%4)) );
......
...@@ -31,6 +31,9 @@ static inline unsigned long calculate_ldr(unsigned long old) ...@@ -31,6 +31,9 @@ static inline unsigned long calculate_ldr(unsigned long old)
#define APIC_BROADCAST_ID (x86_summit ? 0xFF : 0x0F) #define APIC_BROADCAST_ID (x86_summit ? 0xFF : 0x0F)
#define check_apicid_used(bitmap, apicid) (0) #define check_apicid_used(bitmap, apicid) (0)
/* we don't use the phys_cpu_present_map to indicate apicid presence */
#define check_apicid_present(bit) (1)
static inline void clustered_apic_check(void) static inline void clustered_apic_check(void)
{ {
printk("Enabling APIC mode: %s. Using %d I/O APICs\n", printk("Enabling APIC mode: %s. Using %d I/O APICs\n",
...@@ -42,6 +45,13 @@ static inline int apicid_to_node(int logical_apicid) ...@@ -42,6 +45,13 @@ static inline int apicid_to_node(int logical_apicid)
return (logical_apicid >> 5); /* 2 clusterids per CEC */ return (logical_apicid >> 5); /* 2 clusterids per CEC */
} }
/* Mapping from cpu number to logical apicid */
extern volatile u8 cpu_2_logical_apicid[];
static inline int cpu_to_logical_apicid(int cpu)
{
return (int)cpu_2_logical_apicid[cpu];
}
static inline int cpu_present_to_apicid(int mps_cpu) static inline int cpu_present_to_apicid(int mps_cpu)
{ {
if (x86_summit) if (x86_summit)
......
...@@ -76,12 +76,6 @@ static inline int num_booting_cpus(void) ...@@ -76,12 +76,6 @@ static inline int num_booting_cpus(void)
return hweight32(cpu_callout_map); return hweight32(cpu_callout_map);
} }
/* Mapping from cpu number to logical apicid */
extern volatile u8 cpu_2_logical_apicid[];
static inline int cpu_to_logical_apicid(int cpu)
{
return (int)cpu_2_logical_apicid[cpu];
}
extern void map_cpu_to_logical_apicid(void); extern void map_cpu_to_logical_apicid(void);
extern void unmap_cpu_to_logical_apicid(int cpu); extern void unmap_cpu_to_logical_apicid(int cpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment