aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorAlexander Gordeev <agordeev@redhat.com>2012-06-07 09:15:44 -0400
committerIngo Molnar <mingo@kernel.org>2012-06-08 05:44:29 -0400
commit8637e38aff14d048b649075114023023a2e80fba (patch)
treecbafb89d56c83e7a74d2297a490989865e95cccd /arch/x86/kernel
parent1bccd58bfffc5a677051937b332b71f0686187c1 (diff)
x86/apic: Avoid useless scanning thru a cpumask in assign_irq_vector()
In case of static vector allocation domains (i.e. flat) if all vector numbers are exhausted, an attempt to assign a new vector will lead to useless scans through all CPUs in the cpumask, even though it is known that each new pass would fail. Make this corner case less painful by letting report whether the vector allocation domain depends on passed arguments or not and stop scanning early. The same could have been achived by introducing a static flag to the apic operations. But let's allow vector_allocation_domain() have more intelligence here and decide dynamically, in case we would need it in the future. Signed-off-by: Alexander Gordeev <agordeev@redhat.com> Acked-by: Suresh Siddha <suresh.b.siddha@intel.com> Cc: Yinghai Lu <yinghai@kernel.org> Link: http://lkml.kernel.org/r/20120607131542.GE4759@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/apic/apic_noop.c3
-rw-r--r--arch/x86/kernel/apic/io_apic.c12
2 files changed, 11 insertions, 4 deletions
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c
index 3e43cf52893..ac9edf247b1 100644
--- a/arch/x86/kernel/apic/apic_noop.c
+++ b/arch/x86/kernel/apic/apic_noop.c
@@ -100,11 +100,12 @@ 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 bool noop_vector_allocation_domain(int cpu, struct cpumask *retmask)
104{ 104{
105 if (cpu != 0) 105 if (cpu != 0)
106 pr_warning("APIC: Vector allocated for non-BSP cpu\n"); 106 pr_warning("APIC: Vector allocated for non-BSP cpu\n");
107 cpumask_copy(retmask, cpumask_of(cpu)); 107 cpumask_copy(retmask, cpumask_of(cpu));
108 return true;
108} 109}
109 110
110static u32 noop_apic_read(u32 reg) 111static u32 noop_apic_read(u32 reg)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 05af3d341aa..4061a7dee5c 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1137,8 +1137,9 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
1137 for_each_cpu_and(cpu, mask, cpu_online_mask) { 1137 for_each_cpu_and(cpu, mask, cpu_online_mask) {
1138 int new_cpu; 1138 int new_cpu;
1139 int vector, offset; 1139 int vector, offset;
1140 bool more_domains;
1140 1141
1141 apic->vector_allocation_domain(cpu, tmp_mask); 1142 more_domains = apic->vector_allocation_domain(cpu, tmp_mask);
1142 1143
1143 if (cpumask_subset(tmp_mask, cfg->domain)) { 1144 if (cpumask_subset(tmp_mask, cfg->domain)) {
1144 free_cpumask_var(tmp_mask); 1145 free_cpumask_var(tmp_mask);
@@ -1153,8 +1154,13 @@ next:
1153 offset = (offset + 1) % 16; 1154 offset = (offset + 1) % 16;
1154 vector = FIRST_EXTERNAL_VECTOR + offset; 1155 vector = FIRST_EXTERNAL_VECTOR + offset;
1155 } 1156 }
1156 if (unlikely(current_vector == vector)) 1157
1157 continue; 1158 if (unlikely(current_vector == vector)) {
1159 if (more_domains)
1160 continue;
1161 else
1162 break;
1163 }
1158 1164
1159 if (test_bit(vector, used_vectors)) 1165 if (test_bit(vector, used_vectors))
1160 goto next; 1166 goto next;