]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
i40e: Fix Flow Director raw_buf cleanup
authorAlexander Duyck <alexander.h.duyck@intel.com>
Mon, 12 Sep 2016 21:18:39 +0000 (14:18 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sun, 25 Sep 2016 05:15:12 +0000 (22:15 -0700)
The Tx cleanup flow was incorrectly assuming it could check for the flow
director bits after it had unmapped the buffer.  However in this case it
results in us trying to free a raw_buf as though it is an sk_buff.

To fix this I am moving up the flag test for the FD_SB bit so that when
find a non-NULL skb or raw_buf value we then check the flag and use the
appropriate call to free the buffer.

Change-ID: I6284034ba1ea87c9922e56f6eb3181f7f09bddde
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/i40evf/i40e_txrx.c

index 7ada05e7776ff6ab292e19e1fc87ccbeed9abdc1..a2077bedac934aa08500608300e343cb0833f041 100644 (file)
@@ -532,7 +532,10 @@ static void i40e_unmap_and_free_tx_resource(struct i40e_ring *ring,
                                            struct i40e_tx_buffer *tx_buffer)
 {
        if (tx_buffer->skb) {
-               dev_kfree_skb_any(tx_buffer->skb);
+               if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
+                       kfree(tx_buffer->raw_buf);
+               else
+                       dev_kfree_skb_any(tx_buffer->skb);
                if (dma_unmap_len(tx_buffer, len))
                        dma_unmap_single(ring->dev,
                                         dma_unmap_addr(tx_buffer, dma),
@@ -545,9 +548,6 @@ static void i40e_unmap_and_free_tx_resource(struct i40e_ring *ring,
                               DMA_TO_DEVICE);
        }
 
-       if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
-               kfree(tx_buffer->raw_buf);
-
        tx_buffer->next_to_watch = NULL;
        tx_buffer->skb = NULL;
        dma_unmap_len_set(tx_buffer, len, 0);
index e3427ebd5b842af907803f3f7422aaf4ff305a44..cb6b13098699df9b1cae54bb604f37b82a606602 100644 (file)
@@ -51,7 +51,10 @@ static void i40e_unmap_and_free_tx_resource(struct i40e_ring *ring,
                                            struct i40e_tx_buffer *tx_buffer)
 {
        if (tx_buffer->skb) {
-               dev_kfree_skb_any(tx_buffer->skb);
+               if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
+                       kfree(tx_buffer->raw_buf);
+               else
+                       dev_kfree_skb_any(tx_buffer->skb);
                if (dma_unmap_len(tx_buffer, len))
                        dma_unmap_single(ring->dev,
                                         dma_unmap_addr(tx_buffer, dma),
@@ -64,9 +67,6 @@ static void i40e_unmap_and_free_tx_resource(struct i40e_ring *ring,
                               DMA_TO_DEVICE);
        }
 
-       if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
-               kfree(tx_buffer->raw_buf);
-
        tx_buffer->next_to_watch = NULL;
        tx_buffer->skb = NULL;
        dma_unmap_len_set(tx_buffer, len, 0);