Commit 66f81624 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fix from Thomas Gleixner:
 "A single fix for the new matrix allocator to prevent vector exhaustion
  by certain network drivers which allocate gazillions of unused vectors
  which cannot be put into reservation mode due to MSI and the lack of
  MSI entry masking.

  The fix/workaround is to spread the vectors across CPUs by searching
  the supplied target CPU mask for the CPU with the smallest number of
  allocated vectors"

* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  irq/matrix: Spread interrupts on allocation
parents d517bb79 a0c9259d
...@@ -321,15 +321,23 @@ void irq_matrix_remove_reserved(struct irq_matrix *m) ...@@ -321,15 +321,23 @@ void irq_matrix_remove_reserved(struct irq_matrix *m)
int irq_matrix_alloc(struct irq_matrix *m, const struct cpumask *msk, int irq_matrix_alloc(struct irq_matrix *m, const struct cpumask *msk,
bool reserved, unsigned int *mapped_cpu) bool reserved, unsigned int *mapped_cpu)
{ {
unsigned int cpu; unsigned int cpu, best_cpu, maxavl = 0;
struct cpumap *cm;
unsigned int bit;
best_cpu = UINT_MAX;
for_each_cpu(cpu, msk) { for_each_cpu(cpu, msk) {
struct cpumap *cm = per_cpu_ptr(m->maps, cpu); cm = per_cpu_ptr(m->maps, cpu);
unsigned int bit;
if (!cm->online) if (!cm->online || cm->available <= maxavl)
continue; continue;
best_cpu = cpu;
maxavl = cm->available;
}
if (maxavl) {
cm = per_cpu_ptr(m->maps, best_cpu);
bit = matrix_alloc_area(m, cm, 1, false); bit = matrix_alloc_area(m, cm, 1, false);
if (bit < m->alloc_end) { if (bit < m->alloc_end) {
cm->allocated++; cm->allocated++;
...@@ -338,8 +346,8 @@ int irq_matrix_alloc(struct irq_matrix *m, const struct cpumask *msk, ...@@ -338,8 +346,8 @@ int irq_matrix_alloc(struct irq_matrix *m, const struct cpumask *msk,
m->global_available--; m->global_available--;
if (reserved) if (reserved)
m->global_reserved--; m->global_reserved--;
*mapped_cpu = cpu; *mapped_cpu = best_cpu;
trace_irq_matrix_alloc(bit, cpu, m, cm); trace_irq_matrix_alloc(bit, best_cpu, m, cm);
return bit; return bit;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment