|
@@ -899,6 +899,31 @@ static void nicvf_disable_msix(struct nicvf *nic)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void nicvf_set_irq_affinity(struct nicvf *nic)
|
|
|
+{
|
|
|
+ int vec, cpu;
|
|
|
+ int irqnum;
|
|
|
+
|
|
|
+ for (vec = 0; vec < nic->num_vec; vec++) {
|
|
|
+ if (!nic->irq_allocated[vec])
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (!zalloc_cpumask_var(&nic->affinity_mask[vec], GFP_KERNEL))
|
|
|
+ return;
|
|
|
+ /* CQ interrupts */
|
|
|
+ if (vec < NICVF_INTR_ID_SQ)
|
|
|
+ /* Leave CPU0 for RBDR and other interrupts */
|
|
|
+ cpu = nicvf_netdev_qidx(nic, vec) + 1;
|
|
|
+ else
|
|
|
+ cpu = 0;
|
|
|
+
|
|
|
+ cpumask_set_cpu(cpumask_local_spread(cpu, nic->node),
|
|
|
+ nic->affinity_mask[vec]);
|
|
|
+ irqnum = nic->msix_entries[vec].vector;
|
|
|
+ irq_set_affinity_hint(irqnum, nic->affinity_mask[vec]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int nicvf_register_interrupts(struct nicvf *nic)
|
|
|
{
|
|
|
int irq, ret = 0;
|
|
@@ -944,8 +969,13 @@ static int nicvf_register_interrupts(struct nicvf *nic)
|
|
|
ret = request_irq(nic->msix_entries[irq].vector,
|
|
|
nicvf_qs_err_intr_handler,
|
|
|
0, nic->irq_name[irq], nic);
|
|
|
- if (!ret)
|
|
|
- nic->irq_allocated[irq] = true;
|
|
|
+ if (ret)
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ nic->irq_allocated[irq] = true;
|
|
|
+
|
|
|
+ /* Set IRQ affinities */
|
|
|
+ nicvf_set_irq_affinity(nic);
|
|
|
|
|
|
err:
|
|
|
if (ret)
|
|
@@ -963,6 +993,9 @@ static void nicvf_unregister_interrupts(struct nicvf *nic)
|
|
|
if (!nic->irq_allocated[irq])
|
|
|
continue;
|
|
|
|
|
|
+ irq_set_affinity_hint(nic->msix_entries[irq].vector, NULL);
|
|
|
+ free_cpumask_var(nic->affinity_mask[irq]);
|
|
|
+
|
|
|
if (irq < NICVF_INTR_ID_SQ)
|
|
|
free_irq(nic->msix_entries[irq].vector, nic->napi[irq]);
|
|
|
else
|