Commit 7f5b0308 authored by Thomas Falcon's avatar Thomas Falcon Committed by David S. Miller

ibmvnic: Free skb's in cases of failure in transmit

When an error is encountered during transmit we need to free the
skb instead of returning TX_BUSY.
Signed-off-by: default avatarThomas Falcon <tlfalcon@linux.vnet.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3ca19932
...@@ -908,9 +908,13 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -908,9 +908,13 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
be32_to_cpu(adapter->login_rsp_buf-> be32_to_cpu(adapter->login_rsp_buf->
off_txsubm_subcrqs)); off_txsubm_subcrqs));
if (adapter->migrated) { if (adapter->migrated) {
if (!netif_subqueue_stopped(netdev, skb))
netif_stop_subqueue(netdev, queue_num);
dev_kfree_skb_any(skb);
tx_send_failed++; tx_send_failed++;
tx_dropped++; tx_dropped++;
ret = NETDEV_TX_BUSY; ret = NETDEV_TX_OK;
goto out; goto out;
} }
...@@ -976,11 +980,13 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -976,11 +980,13 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
sizeof(tx_buff->indir_arr), sizeof(tx_buff->indir_arr),
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (dma_mapping_error(dev, tx_buff->indir_dma)) { if (dma_mapping_error(dev, tx_buff->indir_dma)) {
dev_kfree_skb_any(skb);
tx_buff->skb = NULL;
if (!firmware_has_feature(FW_FEATURE_CMO)) if (!firmware_has_feature(FW_FEATURE_CMO))
dev_err(dev, "tx: unable to map descriptor array\n"); dev_err(dev, "tx: unable to map descriptor array\n");
tx_map_failed++; tx_map_failed++;
tx_dropped++; tx_dropped++;
ret = NETDEV_TX_BUSY; ret = NETDEV_TX_OK;
goto out; goto out;
} }
lpar_rc = send_subcrq_indirect(adapter, handle_array[queue_num], lpar_rc = send_subcrq_indirect(adapter, handle_array[queue_num],
...@@ -999,9 +1005,15 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -999,9 +1005,15 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
else else
tx_pool->consumer_index--; tx_pool->consumer_index--;
dev_kfree_skb_any(skb);
tx_buff->skb = NULL;
if (lpar_rc == H_CLOSED)
netif_stop_subqueue(netdev, queue_num);
tx_send_failed++; tx_send_failed++;
tx_dropped++; tx_dropped++;
ret = NETDEV_TX_BUSY; ret = NETDEV_TX_OK;
goto out; goto out;
} }
......
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