i40e: Fix Rx hash reported to the stack by our driver
authorAnjali Singhai Jain <anjali.singhai@intel.com>
Wed, 9 Dec 2015 23:50:21 +0000 (15:50 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Sep 2016 06:27:38 +0000 (08:27 +0200)
[ Upstream commit 857942fd1aa15edf7356a4a4bad5369c8e70a633 ]

If the driver calls skb_set_hash even with a zero hash, that
indicates to the stack that the hash calculation is offloaded
in hardware. So the Stack doesn't do a SW hash which is required
for load balancing if the user decides to turn of rx-hashing
on our device.

This patch fixes the path so that we do not call skb_set_hash
if the feature is disabled.

Change-ID: Ic4debfa4ff91b5a72e447348a75768ed7a2d3e1b
Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/i40evf/i40e_txrx.c

index 1e1211875005855b223b3d28f7444fa488df9e59..26c55bba4bf3f81f24ce57b2a8b73d32952e95d9 100644 (file)
@@ -1425,31 +1425,12 @@ checksum_fail:
 }
 
 /**
- * i40e_rx_hash - returns the hash value from the Rx descriptor
- * @ring: descriptor ring
- * @rx_desc: specific descriptor
- **/
-static inline u32 i40e_rx_hash(struct i40e_ring *ring,
-                              union i40e_rx_desc *rx_desc)
-{
-       const __le64 rss_mask =
-               cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
-                           I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
-
-       if ((ring->netdev->features & NETIF_F_RXHASH) &&
-           (rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask)
-               return le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
-       else
-               return 0;
-}
-
-/**
- * i40e_ptype_to_hash - get a hash type
+ * i40e_ptype_to_htype - get a hash type
  * @ptype: the ptype value from the descriptor
  *
  * Returns a hash type to be used by skb_set_hash
  **/
-static inline enum pkt_hash_types i40e_ptype_to_hash(u8 ptype)
+static inline enum pkt_hash_types i40e_ptype_to_htype(u8 ptype)
 {
        struct i40e_rx_ptype_decoded decoded = decode_rx_desc_ptype(ptype);
 
@@ -1466,6 +1447,30 @@ static inline enum pkt_hash_types i40e_ptype_to_hash(u8 ptype)
                return PKT_HASH_TYPE_L2;
 }
 
+/**
+ * i40e_rx_hash - set the hash value in the skb
+ * @ring: descriptor ring
+ * @rx_desc: specific descriptor
+ **/
+static inline void i40e_rx_hash(struct i40e_ring *ring,
+                               union i40e_rx_desc *rx_desc,
+                               struct sk_buff *skb,
+                               u8 rx_ptype)
+{
+       u32 hash;
+       const __le64 rss_mask  =
+               cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
+                           I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
+
+       if (ring->netdev->features & NETIF_F_RXHASH)
+               return;
+
+       if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) {
+               hash = le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
+               skb_set_hash(skb, hash, i40e_ptype_to_htype(rx_ptype));
+       }
+}
+
 /**
  * i40e_clean_rx_irq_ps - Reclaim resources after receive; packet split
  * @rx_ring:  rx ring to clean
@@ -1615,8 +1620,8 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)
                        continue;
                }
 
-               skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
-                            i40e_ptype_to_hash(rx_ptype));
+               i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
+
                if (unlikely(rx_status & I40E_RXD_QW1_STATUS_TSYNVALID_MASK)) {
                        i40e_ptp_rx_hwtstamp(vsi->back, skb, (rx_status &
                                           I40E_RXD_QW1_STATUS_TSYNINDX_MASK) >>
@@ -1745,8 +1750,7 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)
                        continue;
                }
 
-               skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
-                            i40e_ptype_to_hash(rx_ptype));
+               i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
                if (unlikely(rx_status & I40E_RXD_QW1_STATUS_TSYNVALID_MASK)) {
                        i40e_ptp_rx_hwtstamp(vsi->back, skb, (rx_status &
                                           I40E_RXD_QW1_STATUS_TSYNINDX_MASK) >>
index a8a29c374224c19b5e106fbacc79477923f8da84..39db70a597ed65890653c2887ff9bd3406c9d62a 100644 (file)
@@ -879,31 +879,12 @@ checksum_fail:
 }
 
 /**
- * i40e_rx_hash - returns the hash value from the Rx descriptor
- * @ring: descriptor ring
- * @rx_desc: specific descriptor
- **/
-static inline u32 i40e_rx_hash(struct i40e_ring *ring,
-                              union i40e_rx_desc *rx_desc)
-{
-       const __le64 rss_mask =
-               cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
-                           I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
-
-       if ((ring->netdev->features & NETIF_F_RXHASH) &&
-           (rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask)
-               return le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
-       else
-               return 0;
-}
-
-/**
- * i40e_ptype_to_hash - get a hash type
+ * i40e_ptype_to_htype - get a hash type
  * @ptype: the ptype value from the descriptor
  *
  * Returns a hash type to be used by skb_set_hash
  **/
-static inline enum pkt_hash_types i40e_ptype_to_hash(u8 ptype)
+static inline enum pkt_hash_types i40e_ptype_to_htype(u8 ptype)
 {
        struct i40e_rx_ptype_decoded decoded = decode_rx_desc_ptype(ptype);
 
@@ -920,6 +901,30 @@ static inline enum pkt_hash_types i40e_ptype_to_hash(u8 ptype)
                return PKT_HASH_TYPE_L2;
 }
 
+/**
+ * i40e_rx_hash - set the hash value in the skb
+ * @ring: descriptor ring
+ * @rx_desc: specific descriptor
+ **/
+static inline void i40e_rx_hash(struct i40e_ring *ring,
+                               union i40e_rx_desc *rx_desc,
+                               struct sk_buff *skb,
+                               u8 rx_ptype)
+{
+       u32 hash;
+       const __le64 rss_mask  =
+               cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
+                           I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
+
+       if (ring->netdev->features & NETIF_F_RXHASH)
+               return;
+
+       if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) {
+               hash = le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
+               skb_set_hash(skb, hash, i40e_ptype_to_htype(rx_ptype));
+       }
+}
+
 /**
  * i40e_clean_rx_irq_ps - Reclaim resources after receive; packet split
  * @rx_ring:  rx ring to clean
@@ -1061,8 +1066,8 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)
                        continue;
                }
 
-               skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
-                            i40e_ptype_to_hash(rx_ptype));
+               i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
+
                /* probably a little skewed due to removing CRC */
                total_rx_bytes += skb->len;
                total_rx_packets++;
@@ -1179,8 +1184,7 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)
                        continue;
                }
 
-               skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
-                            i40e_ptype_to_hash(rx_ptype));
+               i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
                /* probably a little skewed due to removing CRC */
                total_rx_bytes += skb->len;
                total_rx_packets++;