aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/apic.h9
-rw-r--r--arch/x86/kernel/apic/apic_noop.c3
-rw-r--r--arch/x86/kernel/apic/io_apic.c31
-rw-r--r--arch/x86/kernel/apic/x2apic_cluster.c6
-rw-r--r--arch/x86/kernel/vsmp_64.c3
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
617static inline void 618static inline void
618flat_vector_allocation_domain(int cpu, struct cpumask *retmask) 619flat_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
632static inline void 634static inline void
633default_vector_allocation_domain(int cpu, struct cpumask *retmask) 635default_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
103static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask) 103static 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 */
215static void cluster_vector_allocation_domain(int cpu, struct cpumask *retmask) 215static 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
221static struct apic apic_x2apic_cluster = { 221static 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 */
211static void fill_vector_allocation_domain(int cpu, struct cpumask *retmask) 211static 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}