diff options
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 31 |
1 files changed, 15 insertions, 16 deletions
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 | } |
