diff options
Diffstat (limited to 'arch/x86/kernel/apic/x2apic_cluster.c')
| -rw-r--r-- | arch/x86/kernel/apic/x2apic_cluster.c | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index ff35cff0e1a7..943d03fc6fc4 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
| @@ -81,7 +81,7 @@ static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) | |||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | static void | 83 | static void |
| 84 | x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) | 84 | x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) |
| 85 | { | 85 | { |
| 86 | __x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT); | 86 | __x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT); |
| 87 | } | 87 | } |
| @@ -96,36 +96,37 @@ static void x2apic_send_IPI_all(int vector) | |||
| 96 | __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); | 96 | __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) | 99 | static int |
| 100 | x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | ||
| 101 | const struct cpumask *andmask, | ||
| 102 | unsigned int *apicid) | ||
| 100 | { | 103 | { |
| 101 | /* | 104 | u32 dest = 0; |
| 102 | * We're using fixed IRQ delivery, can only return one logical APIC ID. | 105 | u16 cluster; |
| 103 | * May as well be the first. | 106 | int i; |
| 104 | */ | ||
| 105 | int cpu = cpumask_first(cpumask); | ||
| 106 | 107 | ||
| 107 | if ((unsigned)cpu < nr_cpu_ids) | 108 | for_each_cpu_and(i, cpumask, andmask) { |
| 108 | return per_cpu(x86_cpu_to_logical_apicid, cpu); | 109 | if (!cpumask_test_cpu(i, cpu_online_mask)) |
| 109 | else | 110 | continue; |
| 110 | return BAD_APICID; | 111 | dest = per_cpu(x86_cpu_to_logical_apicid, i); |
| 111 | } | 112 | cluster = x2apic_cluster(i); |
| 113 | break; | ||
| 114 | } | ||
| 112 | 115 | ||
| 113 | static unsigned int | 116 | if (!dest) |
| 114 | x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 117 | return -EINVAL; |
| 115 | const struct cpumask *andmask) | ||
| 116 | { | ||
| 117 | int cpu; | ||
| 118 | 118 | ||
| 119 | /* | 119 | for_each_cpu_and(i, cpumask, andmask) { |
| 120 | * We're using fixed IRQ delivery, can only return one logical APIC ID. | 120 | if (!cpumask_test_cpu(i, cpu_online_mask)) |
| 121 | * May as well be the first. | 121 | continue; |
| 122 | */ | 122 | if (cluster != x2apic_cluster(i)) |
| 123 | for_each_cpu_and(cpu, cpumask, andmask) { | 123 | continue; |
| 124 | if (cpumask_test_cpu(cpu, cpu_online_mask)) | 124 | dest |= per_cpu(x86_cpu_to_logical_apicid, i); |
| 125 | break; | ||
| 126 | } | 125 | } |
| 127 | 126 | ||
| 128 | return per_cpu(x86_cpu_to_logical_apicid, cpu); | 127 | *apicid = dest; |
| 128 | |||
| 129 | return 0; | ||
| 129 | } | 130 | } |
| 130 | 131 | ||
| 131 | static void init_x2apic_ldr(void) | 132 | static void init_x2apic_ldr(void) |
| @@ -208,6 +209,16 @@ static int x2apic_cluster_probe(void) | |||
| 208 | return 0; | 209 | return 0; |
| 209 | } | 210 | } |
| 210 | 211 | ||
| 212 | /* | ||
| 213 | * Each x2apic cluster is an allocation domain. | ||
| 214 | */ | ||
| 215 | static bool cluster_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
| 216 | { | ||
| 217 | cpumask_clear(retmask); | ||
| 218 | cpumask_copy(retmask, per_cpu(cpus_in_cluster, cpu)); | ||
| 219 | return true; | ||
| 220 | } | ||
| 221 | |||
| 211 | static struct apic apic_x2apic_cluster = { | 222 | static struct apic apic_x2apic_cluster = { |
| 212 | 223 | ||
| 213 | .name = "cluster x2apic", | 224 | .name = "cluster x2apic", |
| @@ -219,13 +230,13 @@ static struct apic apic_x2apic_cluster = { | |||
| 219 | .irq_delivery_mode = dest_LowestPrio, | 230 | .irq_delivery_mode = dest_LowestPrio, |
| 220 | .irq_dest_mode = 1, /* logical */ | 231 | .irq_dest_mode = 1, /* logical */ |
| 221 | 232 | ||
| 222 | .target_cpus = x2apic_target_cpus, | 233 | .target_cpus = online_target_cpus, |
| 223 | .disable_esr = 0, | 234 | .disable_esr = 0, |
| 224 | .dest_logical = APIC_DEST_LOGICAL, | 235 | .dest_logical = APIC_DEST_LOGICAL, |
| 225 | .check_apicid_used = NULL, | 236 | .check_apicid_used = NULL, |
| 226 | .check_apicid_present = NULL, | 237 | .check_apicid_present = NULL, |
| 227 | 238 | ||
| 228 | .vector_allocation_domain = x2apic_vector_allocation_domain, | 239 | .vector_allocation_domain = cluster_vector_allocation_domain, |
| 229 | .init_apic_ldr = init_x2apic_ldr, | 240 | .init_apic_ldr = init_x2apic_ldr, |
| 230 | 241 | ||
| 231 | .ioapic_phys_id_map = NULL, | 242 | .ioapic_phys_id_map = NULL, |
| @@ -243,7 +254,6 @@ static struct apic apic_x2apic_cluster = { | |||
| 243 | .set_apic_id = x2apic_set_apic_id, | 254 | .set_apic_id = x2apic_set_apic_id, |
| 244 | .apic_id_mask = 0xFFFFFFFFu, | 255 | .apic_id_mask = 0xFFFFFFFFu, |
| 245 | 256 | ||
| 246 | .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, | ||
| 247 | .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, | 257 | .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, |
| 248 | 258 | ||
| 249 | .send_IPI_mask = x2apic_send_IPI_mask, | 259 | .send_IPI_mask = x2apic_send_IPI_mask, |
