Merge branch 'stmmac-fixes'
[deliverable/linux.git] / drivers / net / ethernet / cavium / thunder / nicvf_main.c
index a009bc30dc4dd36e51c9a1269c28dcb10b8de23f..bfee298fc02abc96e16cae7854d9de3036172542 100644 (file)
@@ -826,7 +826,7 @@ static irqreturn_t nicvf_intr_handler(int irq, void *cq_irq)
        nicvf_disable_intr(nic, NICVF_INTR_CQ, qidx);
 
        /* Schedule NAPI */
-       napi_schedule(&cq_poll->napi);
+       napi_schedule_irqoff(&cq_poll->napi);
 
        /* Clear interrupt */
        nicvf_clear_intr(nic, NICVF_INTR_CQ, qidx);
@@ -897,6 +897,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;
@@ -942,8 +967,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)
@@ -961,6 +991,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
@@ -1394,6 +1427,7 @@ static void nicvf_tx_timeout(struct net_device *dev)
                netdev_warn(dev, "%s: Transmit timed out, resetting\n",
                            dev->name);
 
+       nic->drv_stats.tx_timeout++;
        schedule_work(&nic->reset_task);
 }
 
This page took 0.029191 seconds and 5 git commands to generate.