net: thunderx: Assign affinity hints to vf's interrupts
authorSunil Goutham <sgoutham@cavium.com>
Thu, 11 Feb 2016 16:20:23 +0000 (21:50 +0530)
committerDavid S. Miller <davem@davemloft.net>
Thu, 11 Feb 2016 16:30:26 +0000 (11:30 -0500)
This affinity hint can be used by user space irqbalance tool to set
preferred CPU mask for irqs registered by this VF. Irqbalance needs
to be in 'exact' mode to set irq affinity same as indicated by
affinity hint.

Signed-off-by: Sunil Goutham <sgoutham@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/cavium/thunder/nic.h
drivers/net/ethernet/cavium/thunder/nicvf_main.c

index 8af363a9af6037487c472fde9e1fe8da70e4bf41..00cc9156abbbc06263a0ca146c7d94b1d75710f1 100644 (file)
@@ -309,6 +309,7 @@ struct nicvf {
        struct msix_entry       msix_entries[NIC_VF_MSIX_VECTORS];
        char                    irq_name[NIC_VF_MSIX_VECTORS][20];
        bool                    irq_allocated[NIC_VF_MSIX_VECTORS];
+       cpumask_var_t           affinity_mask[NIC_VF_MSIX_VECTORS];
 
        /* VF <-> PF mailbox communication */
        bool                    pf_acked;
index c6f146cf266de6bc329e5f7f02b4a083528cbf3e..90ce93e380e11041b70602546e3807b15992c82c 100644 (file)
@@ -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