fm10k: initialize xps at driver load
authorJacob Keller <jacob.e.keller@intel.com>
Thu, 29 Oct 2015 20:43:40 +0000 (13:43 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sun, 13 Dec 2015 23:28:43 +0000 (15:28 -0800)
Similar to ixgbe and i40e, initialize XPS on driver load so that we can
take advantage of this kernel feature.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Krishneil Singh <krishneil.k.singh@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/fm10k/fm10k.h
drivers/net/ethernet/intel/fm10k/fm10k_pci.c

index 021abe301f2fe07e8238228e7a9118322df3eb6b..b34bb008b1045a0163fe9b4bb2acb93e7c861f42 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/types.h>
 #include <linux/etherdevice.h>
+#include <linux/cpumask.h>
 #include <linux/rtnetlink.h>
 #include <linux/if_vlan.h>
 #include <linux/pci.h>
@@ -66,6 +67,7 @@ struct fm10k_l2_accel {
 enum fm10k_ring_state_t {
        __FM10K_TX_DETECT_HANG,
        __FM10K_HANG_CHECK_ARMED,
+       __FM10K_TX_XPS_INIT_DONE,
 };
 
 #define check_for_tx_hang(ring) \
@@ -209,6 +211,7 @@ struct fm10k_q_vector {
        struct fm10k_ring_container rx, tx;
 
        struct napi_struct napi;
+       cpumask_t affinity_mask;
        char name[IFNAMSIZ + 9];
 
 #ifdef CONFIG_DEBUG_FS
index e820b5f34eeb4b9da7ca785f8fc1bc6d074cbf50..020f6dce41544cd69f21f5bbd2d14df67b01bf6b 100644 (file)
@@ -601,6 +601,13 @@ static void fm10k_configure_tx_ring(struct fm10k_intfc *interface,
        fm10k_write_reg(hw, FM10K_PFVTCTL(reg_idx),
                        FM10K_PFVTCTL_FTAG_DESC_ENABLE);
 
+       /* Initialize XPS */
+       if (!test_and_set_bit(__FM10K_TX_XPS_INIT_DONE, &ring->state) &&
+           ring->q_vector)
+               netif_set_xps_queue(ring->netdev,
+                                   &ring->q_vector->affinity_mask,
+                                   ring->queue_index);
+
        /* enable queue */
        fm10k_write_reg(hw, FM10K_TXDCTL(reg_idx), txdctl);
 }
@@ -1488,8 +1495,10 @@ void fm10k_qv_free_irq(struct fm10k_intfc *interface)
                if (!q_vector->tx.count && !q_vector->rx.count)
                        continue;
 
-               /* disable interrupts */
+               /* clear the affinity_mask in the IRQ descriptor */
+               irq_set_affinity_hint(entry->vector, NULL);
 
+               /* disable interrupts */
                writel(FM10K_ITR_MASK_SET, q_vector->itr);
 
                free_irq(entry->vector, q_vector);
@@ -1547,6 +1556,9 @@ int fm10k_qv_request_irq(struct fm10k_intfc *interface)
                        goto err_out;
                }
 
+               /* assign the mask for this irq */
+               irq_set_affinity_hint(entry->vector, &q_vector->affinity_mask);
+
                /* Enable q_vector */
                writel(FM10K_ITR_ENABLE, q_vector->itr);
 
@@ -1567,8 +1579,10 @@ err_out:
                if (!q_vector->tx.count && !q_vector->rx.count)
                        continue;
 
-               /* disable interrupts */
+               /* clear the affinity_mask in the IRQ descriptor */
+               irq_set_affinity_hint(entry->vector, NULL);
 
+               /* disable interrupts */
                writel(FM10K_ITR_MASK_SET, q_vector->itr);
 
                free_irq(entry->vector, q_vector);