Commit aa9d22dd authored by Yunsheng Lin's avatar Yunsheng Lin Committed by David S. Miller

net: hns3: fix error handling for desc filling

When desc filling fails in hns3_nic_net_xmit, it will call
hns3_clear_desc to unmap the dma mapping. But currently the
ring->next_to_use points to the desc where the desc filling
or dma mapping return error, which means the desc that
ring->next_to_use points to has not done the dma mapping,
the desc that need unmapping is before the ring->next_to_use.

This patch fixes it by calling ring_ptr_move_bw(next_to_use)
before doing unmapping operation, and set desc_cb->dma to
zero to avoid freeing it again when unloading.

Also, when filling skb head or frag fails, both need to unmap
all the way back to next_to_use_head, so remove one desc filling
error handling.

Fixes: 76ad4f0e ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 757cd1e4
...@@ -1224,6 +1224,9 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig) ...@@ -1224,6 +1224,9 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
if (ring->next_to_use == next_to_use_orig) if (ring->next_to_use == next_to_use_orig)
break; break;
/* rollback one */
ring_ptr_move_bw(ring, next_to_use);
/* unmap the descriptor dma address */ /* unmap the descriptor dma address */
if (ring->desc_cb[ring->next_to_use].type == DESC_TYPE_SKB) if (ring->desc_cb[ring->next_to_use].type == DESC_TYPE_SKB)
dma_unmap_single(dev, dma_unmap_single(dev,
...@@ -1237,9 +1240,7 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig) ...@@ -1237,9 +1240,7 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
DMA_TO_DEVICE); DMA_TO_DEVICE);
ring->desc_cb[ring->next_to_use].length = 0; ring->desc_cb[ring->next_to_use].length = 0;
ring->desc_cb[ring->next_to_use].dma = 0;
/* rollback one */
ring_ptr_move_bw(ring, next_to_use);
} }
} }
...@@ -1252,7 +1253,6 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1252,7 +1253,6 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
struct netdev_queue *dev_queue; struct netdev_queue *dev_queue;
struct skb_frag_struct *frag; struct skb_frag_struct *frag;
int next_to_use_head; int next_to_use_head;
int next_to_use_frag;
int buf_num; int buf_num;
int seg_num; int seg_num;
int size; int size;
...@@ -1291,9 +1291,8 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1291,9 +1291,8 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
ret = hns3_fill_desc(ring, skb, size, seg_num == 1 ? 1 : 0, ret = hns3_fill_desc(ring, skb, size, seg_num == 1 ? 1 : 0,
DESC_TYPE_SKB); DESC_TYPE_SKB);
if (unlikely(ret)) if (unlikely(ret))
goto head_fill_err; goto fill_err;
next_to_use_frag = ring->next_to_use;
/* Fill the fragments */ /* Fill the fragments */
for (i = 1; i < seg_num; i++) { for (i = 1; i < seg_num; i++) {
frag = &skb_shinfo(skb)->frags[i - 1]; frag = &skb_shinfo(skb)->frags[i - 1];
...@@ -1304,7 +1303,7 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1304,7 +1303,7 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
DESC_TYPE_PAGE); DESC_TYPE_PAGE);
if (unlikely(ret)) if (unlikely(ret))
goto frag_fill_err; goto fill_err;
} }
/* Complete translate all packets */ /* Complete translate all packets */
...@@ -1317,10 +1316,7 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1317,10 +1316,7 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK; return NETDEV_TX_OK;
frag_fill_err: fill_err:
hns3_clear_desc(ring, next_to_use_frag);
head_fill_err:
hns3_clear_desc(ring, next_to_use_head); hns3_clear_desc(ring, next_to_use_head);
out_err_tx_ok: out_err_tx_ok:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment