aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2009-03-18 21:12:50 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-20 04:17:20 -0400
commit1b7719c4559dc1522065d4cfd033f8bb8f969159 (patch)
treed38b95cbe779ac1d9db46f3460d760653bce8dc0 /drivers/net
parent8c81c9c315b7e7e240906fab0e8dde1595101bd2 (diff)
e1000e: fix dma error handling issues
There were a few issues I noticed in e1000e. These include a double free of the skb if mapping fails, and the fact that context descriptors appear to be left in the descriptor ring after the failure. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/e1000e/netdev.c76
1 files changed, 32 insertions, 44 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 402d2dd7d68f..da876d59a9ca 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -574,6 +574,7 @@ static void e1000_put_txbuf(struct e1000_adapter *adapter,
574 dev_kfree_skb_any(buffer_info->skb); 574 dev_kfree_skb_any(buffer_info->skb);
575 buffer_info->skb = NULL; 575 buffer_info->skb = NULL;
576 } 576 }
577 buffer_info->time_stamp = 0;
577} 578}
578 579
579static void e1000_print_tx_hang(struct e1000_adapter *adapter) 580static void e1000_print_tx_hang(struct e1000_adapter *adapter)
@@ -678,17 +679,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
678 } 679 }
679 680
680 if (adapter->detect_tx_hung) { 681 if (adapter->detect_tx_hung) {
681 /* 682 /* Detect a transmit hang in hardware, this serializes the
682 * Detect a transmit hang in hardware, this serializes the 683 * check with the clearing of time_stamp and movement of i */
683 * check with the clearing of time_stamp and movement of i
684 */
685 adapter->detect_tx_hung = 0; 684 adapter->detect_tx_hung = 0;
686 /* 685 if (tx_ring->buffer_info[eop].time_stamp &&
687 * read barrier to make sure that the ->dma member and time
688 * stamp are updated fully
689 */
690 smp_rmb();
691 if (tx_ring->buffer_info[eop].dma &&
692 time_after(jiffies, tx_ring->buffer_info[eop].time_stamp 686 time_after(jiffies, tx_ring->buffer_info[eop].time_stamp
693 + (adapter->tx_timeout_factor * HZ)) 687 + (adapter->tx_timeout_factor * HZ))
694 && !(er32(STATUS) & E1000_STATUS_TXOFF)) { 688 && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
@@ -3824,39 +3818,41 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
3824 unsigned int mss) 3818 unsigned int mss)
3825{ 3819{
3826 struct e1000_ring *tx_ring = adapter->tx_ring; 3820 struct e1000_ring *tx_ring = adapter->tx_ring;
3821 struct e1000_buffer *buffer_info;
3827 unsigned int len = skb_headlen(skb); 3822 unsigned int len = skb_headlen(skb);
3828 unsigned int offset, size, count = 0, i; 3823 unsigned int offset, size, count = 0, i;
3829 unsigned int f; 3824 unsigned int f;
3830 dma_addr_t map; 3825 dma_addr_t *map;
3831 3826
3832 i = tx_ring->next_to_use; 3827 i = tx_ring->next_to_use;
3833 3828
3834 if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) { 3829 if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
3835 dev_err(&adapter->pdev->dev, "TX DMA map failed\n"); 3830 dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
3836 adapter->tx_dma_failed++; 3831 adapter->tx_dma_failed++;
3837 dev_kfree_skb(skb); 3832 return 0;
3838 return -2;
3839 } 3833 }
3840 3834
3841 map = skb_shinfo(skb)->dma_maps[0]; 3835 map = skb_shinfo(skb)->dma_maps;
3842 offset = 0; 3836 offset = 0;
3843 3837
3844 while (len) { 3838 while (len) {
3845 struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i]; 3839 buffer_info = &tx_ring->buffer_info[i];
3846 size = min(len, max_per_txd); 3840 size = min(len, max_per_txd);
3847 3841
3848 buffer_info->length = size; 3842 buffer_info->length = size;
3849 /* set time_stamp *before* dma to help avoid a possible race */
3850 buffer_info->time_stamp = jiffies; 3843 buffer_info->time_stamp = jiffies;
3851 buffer_info->dma = map + offset;
3852 buffer_info->next_to_watch = i; 3844 buffer_info->next_to_watch = i;
3845 buffer_info->dma = map[0] + offset;
3846 count++;
3853 3847
3854 len -= size; 3848 len -= size;
3855 offset += size; 3849 offset += size;
3856 count++; 3850
3857 i++; 3851 if (len) {
3858 if (i == tx_ring->count) 3852 i++;
3859 i = 0; 3853 if (i == tx_ring->count)
3854 i = 0;
3855 }
3860 } 3856 }
3861 3857
3862 for (f = 0; f < nr_frags; f++) { 3858 for (f = 0; f < nr_frags; f++) {
@@ -3864,37 +3860,29 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
3864 3860
3865 frag = &skb_shinfo(skb)->frags[f]; 3861 frag = &skb_shinfo(skb)->frags[f];
3866 len = frag->size; 3862 len = frag->size;
3867 map = skb_shinfo(skb)->dma_maps[f + 1];
3868 offset = 0; 3863 offset = 0;
3869 3864
3870 while (len) { 3865 while (len) {
3871 struct e1000_buffer *buffer_info; 3866 i++;
3867 if (i == tx_ring->count)
3868 i = 0;
3869
3872 buffer_info = &tx_ring->buffer_info[i]; 3870 buffer_info = &tx_ring->buffer_info[i];
3873 size = min(len, max_per_txd); 3871 size = min(len, max_per_txd);
3874 3872
3875 buffer_info->length = size; 3873 buffer_info->length = size;
3876 buffer_info->time_stamp = jiffies; 3874 buffer_info->time_stamp = jiffies;
3877 buffer_info->dma = map + offset;
3878 buffer_info->next_to_watch = i; 3875 buffer_info->next_to_watch = i;
3876 buffer_info->dma = map[f + 1] + offset;
3879 3877
3880 len -= size; 3878 len -= size;
3881 offset += size; 3879 offset += size;
3882 count++; 3880 count++;
3883
3884 i++;
3885 if (i == tx_ring->count)
3886 i = 0;
3887 } 3881 }
3888 } 3882 }
3889 3883
3890 if (i == 0)
3891 i = tx_ring->count - 1;
3892 else
3893 i--;
3894
3895 tx_ring->buffer_info[i].skb = skb; 3884 tx_ring->buffer_info[i].skb = skb;
3896 tx_ring->buffer_info[first].next_to_watch = i; 3885 tx_ring->buffer_info[first].next_to_watch = i;
3897 smp_wmb();
3898 3886
3899 return count; 3887 return count;
3900} 3888}
@@ -4145,20 +4133,20 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
4145 if (skb->protocol == htons(ETH_P_IP)) 4133 if (skb->protocol == htons(ETH_P_IP))
4146 tx_flags |= E1000_TX_FLAGS_IPV4; 4134 tx_flags |= E1000_TX_FLAGS_IPV4;
4147 4135
4136 /* if count is 0 then mapping error has occured */
4148 count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss); 4137 count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
4149 if (count < 0) { 4138 if (count) {
4150 /* handle pci_map_single() error in e1000_tx_map */ 4139 e1000_tx_queue(adapter, tx_flags, count);
4140 netdev->trans_start = jiffies;
4141 /* Make sure there is space in the ring for the next send. */
4142 e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
4143
4144 } else {
4151 dev_kfree_skb_any(skb); 4145 dev_kfree_skb_any(skb);
4152 return NETDEV_TX_OK; 4146 tx_ring->buffer_info[first].time_stamp = 0;
4147 tx_ring->next_to_use = first;
4153 } 4148 }
4154 4149
4155 e1000_tx_queue(adapter, tx_flags, count);
4156
4157 netdev->trans_start = jiffies;
4158
4159 /* Make sure there is space in the ring for the next send. */
4160 e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
4161
4162 return NETDEV_TX_OK; 4150 return NETDEV_TX_OK;
4163} 4151}
4164 4152