diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2014-03-15 18:58:10 -0400 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2014-03-25 00:18:54 -0400 |
commit | 07641c8fa45774d5e99f4bdc8c37a7d174a2e973 (patch) | |
tree | ab0bf0b68762265c17c3766489ec2285f527c99a | |
parent | 548ff1ed7d251a5de40e2dfb3ec5f317ee834082 (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.c | 20 |
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 | ||
834 | static inline void atl1c_clean_buffer(struct pci_dev *pdev, | 834 | static 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); |