aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2014-03-15 18:58:10 -0400
committerEric W. Biederman <ebiederm@xmission.com>2014-03-25 00:18:54 -0400
commit07641c8fa45774d5e99f4bdc8c37a7d174a2e973 (patch)
treeab0bf0b68762265c17c3766489ec2285f527c99a
parent548ff1ed7d251a5de40e2dfb3ec5f317ee834082 (diff)
atl1c: Call dev_kfree/consume_skb_any instead of dev_kfree_skb.
The call path: atl1c_xmit_frame, atlc_tx_rollback, atl1c_clean_buffer can not be tell at compile time if it will be invoked from hard irq or other context, as atl1c_xmit_frame does not know. So remove the logic that passes the compile time knowledge into al1c_clean_buffer and figure out it out at runtime with dev_consume_skb_any. Replace dev_kfree_skb with dev_kfree_skb_any in atl1c_xmit_frame that can be called in hard irq and other contexts. Replace dev_kfree_skb and dev_kfree_skb_irq with dev_consume_skb_any in atl1c_clean_buffer that can be called in hard irq and other contexts. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 4d3258dd0a88..31f262302128 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -832,7 +832,7 @@ static int atl1c_sw_init(struct atl1c_adapter *adapter)
832} 832}
833 833
834static inline void atl1c_clean_buffer(struct pci_dev *pdev, 834static inline void atl1c_clean_buffer(struct pci_dev *pdev,
835 struct atl1c_buffer *buffer_info, int in_irq) 835 struct atl1c_buffer *buffer_info)
836{ 836{
837 u16 pci_driection; 837 u16 pci_driection;
838 if (buffer_info->flags & ATL1C_BUFFER_FREE) 838 if (buffer_info->flags & ATL1C_BUFFER_FREE)
@@ -850,12 +850,8 @@ static inline void atl1c_clean_buffer(struct pci_dev *pdev,
850 pci_unmap_page(pdev, buffer_info->dma, 850 pci_unmap_page(pdev, buffer_info->dma,
851 buffer_info->length, pci_driection); 851 buffer_info->length, pci_driection);
852 } 852 }
853 if (buffer_info->skb) { 853 if (buffer_info->skb)
854 if (in_irq) 854 dev_consume_skb_any(buffer_info->skb);
855 dev_kfree_skb_irq(buffer_info->skb);
856 else
857 dev_kfree_skb(buffer_info->skb);
858 }
859 buffer_info->dma = 0; 855 buffer_info->dma = 0;
860 buffer_info->skb = NULL; 856 buffer_info->skb = NULL;
861 ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE); 857 ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
@@ -875,7 +871,7 @@ static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter,
875 ring_count = tpd_ring->count; 871 ring_count = tpd_ring->count;
876 for (index = 0; index < ring_count; index++) { 872 for (index = 0; index < ring_count; index++) {
877 buffer_info = &tpd_ring->buffer_info[index]; 873 buffer_info = &tpd_ring->buffer_info[index];
878 atl1c_clean_buffer(pdev, buffer_info, 0); 874 atl1c_clean_buffer(pdev, buffer_info);
879 } 875 }
880 876
881 /* Zero out Tx-buffers */ 877 /* Zero out Tx-buffers */
@@ -899,7 +895,7 @@ static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter)
899 895
900 for (j = 0; j < rfd_ring->count; j++) { 896 for (j = 0; j < rfd_ring->count; j++) {
901 buffer_info = &rfd_ring->buffer_info[j]; 897 buffer_info = &rfd_ring->buffer_info[j];
902 atl1c_clean_buffer(pdev, buffer_info, 0); 898 atl1c_clean_buffer(pdev, buffer_info);
903 } 899 }
904 /* zero out the descriptor ring */ 900 /* zero out the descriptor ring */
905 memset(rfd_ring->desc, 0, rfd_ring->size); 901 memset(rfd_ring->desc, 0, rfd_ring->size);
@@ -1562,7 +1558,7 @@ static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,
1562 1558
1563 while (next_to_clean != hw_next_to_clean) { 1559 while (next_to_clean != hw_next_to_clean) {
1564 buffer_info = &tpd_ring->buffer_info[next_to_clean]; 1560 buffer_info = &tpd_ring->buffer_info[next_to_clean];
1565 atl1c_clean_buffer(pdev, buffer_info, 1); 1561 atl1c_clean_buffer(pdev, buffer_info);
1566 if (++next_to_clean == tpd_ring->count) 1562 if (++next_to_clean == tpd_ring->count)
1567 next_to_clean = 0; 1563 next_to_clean = 0;
1568 atomic_set(&tpd_ring->next_to_clean, next_to_clean); 1564 atomic_set(&tpd_ring->next_to_clean, next_to_clean);
@@ -2085,7 +2081,7 @@ static void atl1c_tx_rollback(struct atl1c_adapter *adpt,
2085 while (index != tpd_ring->next_to_use) { 2081 while (index != tpd_ring->next_to_use) {
2086 tpd = ATL1C_TPD_DESC(tpd_ring, index); 2082 tpd = ATL1C_TPD_DESC(tpd_ring, index);
2087 buffer_info = &tpd_ring->buffer_info[index]; 2083 buffer_info = &tpd_ring->buffer_info[index];
2088 atl1c_clean_buffer(adpt->pdev, buffer_info, 0); 2084 atl1c_clean_buffer(adpt->pdev, buffer_info);
2089 memset(tpd, 0, sizeof(struct atl1c_tpd_desc)); 2085 memset(tpd, 0, sizeof(struct atl1c_tpd_desc));
2090 if (++index == tpd_ring->count) 2086 if (++index == tpd_ring->count)
2091 index = 0; 2087 index = 0;
@@ -2258,7 +2254,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
2258 /* roll back tpd/buffer */ 2254 /* roll back tpd/buffer */
2259 atl1c_tx_rollback(adapter, tpd, type); 2255 atl1c_tx_rollback(adapter, tpd, type);
2260 spin_unlock_irqrestore(&adapter->tx_lock, flags); 2256 spin_unlock_irqrestore(&adapter->tx_lock, flags);
2261 dev_kfree_skb(skb); 2257 dev_kfree_skb_any(skb);
2262 } else { 2258 } else {
2263 atl1c_tx_queue(adapter, skb, tpd, type); 2259 atl1c_tx_queue(adapter, skb, tpd, type);
2264 spin_unlock_irqrestore(&adapter->tx_lock, flags); 2260 spin_unlock_irqrestore(&adapter->tx_lock, flags);