diff options
| -rw-r--r-- | arch/x86/include/asm/apic.h | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/apic_noop.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 31 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/x2apic_cluster.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/vsmp_64.c | 3 |
5 files changed, 28 insertions, 24 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 8bebeb8952fb..88093c1d44fd 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
| @@ -306,7 +306,8 @@ struct apic { | |||
| 306 | unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid); | 306 | unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid); |
| 307 | unsigned long (*check_apicid_present)(int apicid); | 307 | unsigned long (*check_apicid_present)(int apicid); |
| 308 | 308 | ||
| 309 | void (*vector_allocation_domain)(int cpu, struct cpumask *retmask); | 309 | void (*vector_allocation_domain)(int cpu, struct cpumask *retmask, |
| 310 | const struct cpumask *mask); | ||
| 310 | void (*init_apic_ldr)(void); | 311 | void (*init_apic_ldr)(void); |
| 311 | 312 | ||
| 312 | void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap); | 313 | void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap); |
| @@ -615,7 +616,8 @@ default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | |||
| 615 | unsigned int *apicid); | 616 | unsigned int *apicid); |
| 616 | 617 | ||
| 617 | static inline void | 618 | static inline void |
| 618 | flat_vector_allocation_domain(int cpu, struct cpumask *retmask) | 619 | flat_vector_allocation_domain(int cpu, struct cpumask *retmask, |
| 620 | const struct cpumask *mask) | ||
| 619 | { | 621 | { |
| 620 | /* Careful. Some cpus do not strictly honor the set of cpus | 622 | /* Careful. Some cpus do not strictly honor the set of cpus |
| 621 | * specified in the interrupt destination when using lowest | 623 | * specified in the interrupt destination when using lowest |
| @@ -630,7 +632,8 @@ flat_vector_allocation_domain(int cpu, struct cpumask *retmask) | |||
| 630 | } | 632 | } |
| 631 | 633 | ||
| 632 | static inline void | 634 | static inline void |
| 633 | default_vector_allocation_domain(int cpu, struct cpumask *retmask) | 635 | default_vector_allocation_domain(int cpu, struct cpumask *retmask, |
| 636 | const struct cpumask *mask) | ||
| 634 | { | 637 | { |
| 635 | cpumask_copy(retmask, cpumask_of(cpu)); | 638 | cpumask_copy(retmask, cpumask_of(cpu)); |
| 636 | } | 639 | } |
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index 08c337bc49ff..e145f28b4099 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c | |||
| @@ -100,7 +100,8 @@ static unsigned long noop_check_apicid_present(int bit) | |||
| 100 | return physid_isset(bit, phys_cpu_present_map); | 100 | return physid_isset(bit, phys_cpu_present_map); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask) | 103 | static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask, |
| 104 | const struct cpumask *mask) | ||
| 104 | { | 105 | { |
| 105 | if (cpu != 0) | 106 | if (cpu != 0) |
| 106 | pr_warning("APIC: Vector allocated for non-BSP cpu\n"); | 107 | pr_warning("APIC: Vector allocated for non-BSP cpu\n"); |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 8a08f09aa505..9684f963befe 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -1113,7 +1113,6 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) | |||
| 1113 | */ | 1113 | */ |
| 1114 | static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START; | 1114 | static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START; |
| 1115 | static int current_offset = VECTOR_OFFSET_START % 16; | 1115 | static int current_offset = VECTOR_OFFSET_START % 16; |
| 1116 | unsigned int old_vector; | ||
| 1117 | int cpu, err; | 1116 | int cpu, err; |
| 1118 | cpumask_var_t tmp_mask; | 1117 | cpumask_var_t tmp_mask; |
| 1119 | 1118 | ||
| @@ -1123,28 +1122,28 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) | |||
| 1123 | if (!alloc_cpumask_var(&tmp_mask, GFP_ATOMIC)) | 1122 | if (!alloc_cpumask_var(&tmp_mask, GFP_ATOMIC)) |
| 1124 | return -ENOMEM; | 1123 | return -ENOMEM; |
| 1125 | 1124 | ||
| 1126 | old_vector = cfg->vector; | ||
| 1127 | if (old_vector) { | ||
| 1128 | cpumask_and(tmp_mask, mask, cpu_online_mask); | ||
| 1129 | if (cpumask_subset(tmp_mask, cfg->domain)) { | ||
| 1130 | free_cpumask_var(tmp_mask); | ||
| 1131 | return 0; | ||
| 1132 | } | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | /* Only try and allocate irqs on cpus that are present */ | 1125 | /* Only try and allocate irqs on cpus that are present */ |
| 1136 | err = -ENOSPC; | 1126 | err = -ENOSPC; |
| 1137 | cpumask_clear(cfg->old_domain); | 1127 | cpumask_clear(cfg->old_domain); |
| 1138 | cpu = cpumask_first_and(mask, cpu_online_mask); | 1128 | cpu = cpumask_first_and(mask, cpu_online_mask); |
| 1139 | while (cpu < nr_cpu_ids) { | 1129 | while (cpu < nr_cpu_ids) { |
| 1140 | int new_cpu; | 1130 | int new_cpu, vector, offset; |
| 1141 | int vector, offset; | ||
| 1142 | 1131 | ||
| 1143 | apic->vector_allocation_domain(cpu, tmp_mask); | 1132 | apic->vector_allocation_domain(cpu, tmp_mask, mask); |
| 1144 | 1133 | ||
| 1145 | if (cpumask_subset(tmp_mask, cfg->domain)) { | 1134 | if (cpumask_subset(tmp_mask, cfg->domain)) { |
| 1146 | free_cpumask_var(tmp_mask); | 1135 | err = 0; |
| 1147 | return 0; | 1136 | if (cpumask_equal(tmp_mask, cfg->domain)) |
| 1137 | break; | ||
| 1138 | /* | ||
| 1139 | * New cpumask using the vector is a proper subset of | ||
| 1140 | * the current in use mask. So cleanup the vector | ||
| 1141 | * allocation for the members that are not used anymore. | ||
| 1142 | */ | ||
| 1143 | cpumask_andnot(cfg->old_domain, cfg->domain, tmp_mask); | ||
| 1144 | cfg->move_in_progress = 1; | ||
| 1145 | cpumask_and(cfg->domain, cfg->domain, tmp_mask); | ||
| 1146 | break; | ||
| 1148 | } | 1147 | } |
| 1149 | 1148 | ||
| 1150 | vector = current_vector; | 1149 | vector = current_vector; |
| @@ -1172,7 +1171,7 @@ next: | |||
| 1172 | /* Found one! */ | 1171 | /* Found one! */ |
| 1173 | current_vector = vector; | 1172 | current_vector = vector; |
| 1174 | current_offset = offset; | 1173 | current_offset = offset; |
| 1175 | if (old_vector) { | 1174 | if (cfg->vector) { |
| 1176 | cfg->move_in_progress = 1; | 1175 | cfg->move_in_progress = 1; |
| 1177 | cpumask_copy(cfg->old_domain, cfg->domain); | 1176 | cpumask_copy(cfg->old_domain, cfg->domain); |
| 1178 | } | 1177 | } |
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index b5d889b5659a..bde78d0098a4 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
| @@ -212,10 +212,10 @@ static int x2apic_cluster_probe(void) | |||
| 212 | /* | 212 | /* |
| 213 | * Each x2apic cluster is an allocation domain. | 213 | * Each x2apic cluster is an allocation domain. |
| 214 | */ | 214 | */ |
| 215 | static void cluster_vector_allocation_domain(int cpu, struct cpumask *retmask) | 215 | static void cluster_vector_allocation_domain(int cpu, struct cpumask *retmask, |
| 216 | const struct cpumask *mask) | ||
| 216 | { | 217 | { |
| 217 | cpumask_clear(retmask); | 218 | cpumask_and(retmask, mask, per_cpu(cpus_in_cluster, cpu)); |
| 218 | cpumask_copy(retmask, per_cpu(cpus_in_cluster, cpu)); | ||
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | static struct apic apic_x2apic_cluster = { | 221 | static struct apic apic_x2apic_cluster = { |
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 3f0285ac00fa..992f890283e9 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c | |||
| @@ -208,7 +208,8 @@ static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) | |||
| 208 | * In vSMP, all cpus should be capable of handling interrupts, regardless of | 208 | * In vSMP, all cpus should be capable of handling interrupts, regardless of |
| 209 | * the APIC used. | 209 | * the APIC used. |
| 210 | */ | 210 | */ |
| 211 | static void fill_vector_allocation_domain(int cpu, struct cpumask *retmask) | 211 | static void fill_vector_allocation_domain(int cpu, struct cpumask *retmask, |
| 212 | const struct cpumask *mask) | ||
| 212 | { | 213 | { |
| 213 | cpumask_setall(retmask); | 214 | cpumask_setall(retmask); |
| 214 | } | 215 | } |
