aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Falcon <tlfalcon@linux.vnet.ibm.com>2018-02-18 11:08:41 -0500
committerDavid S. Miller <davem@davemloft.net>2018-02-20 13:16:55 -0500
commitffc385b95adb0e601f6858b06401adabedf59f81 (patch)
tree1556f5daa6639b443a351772d55da6c816a3404a
parentf5c0c6f4299f870f074235fbf552ecf957fc249c (diff)
ibmvnic: Keep track of supplementary TX descriptors
Supplementary TX descriptors were not being accounted for, which was resulting in an overflow of the hardware device's transmit queue. Keep track of those descriptors now when determining how many entries remain on the TX queue. Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c8
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.h1
2 files changed, 7 insertions, 2 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 996f47568f9e..64770a1c406d 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1467,6 +1467,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1467 if ((*hdrs >> 7) & 1) { 1467 if ((*hdrs >> 7) & 1) {
1468 build_hdr_descs_arr(tx_buff, &num_entries, *hdrs); 1468 build_hdr_descs_arr(tx_buff, &num_entries, *hdrs);
1469 tx_crq.v1.n_crq_elem = num_entries; 1469 tx_crq.v1.n_crq_elem = num_entries;
1470 tx_buff->num_entries = num_entries;
1470 tx_buff->indir_arr[0] = tx_crq; 1471 tx_buff->indir_arr[0] = tx_crq;
1471 tx_buff->indir_dma = dma_map_single(dev, tx_buff->indir_arr, 1472 tx_buff->indir_dma = dma_map_single(dev, tx_buff->indir_arr,
1472 sizeof(tx_buff->indir_arr), 1473 sizeof(tx_buff->indir_arr),
@@ -1515,7 +1516,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1515 goto out; 1516 goto out;
1516 } 1517 }
1517 1518
1518 if (atomic_inc_return(&tx_scrq->used) 1519 if (atomic_add_return(num_entries, &tx_scrq->used)
1519 >= adapter->req_tx_entries_per_subcrq) { 1520 >= adapter->req_tx_entries_per_subcrq) {
1520 netdev_info(netdev, "Stopping queue %d\n", queue_num); 1521 netdev_info(netdev, "Stopping queue %d\n", queue_num);
1521 netif_stop_subqueue(netdev, queue_num); 1522 netif_stop_subqueue(netdev, queue_num);
@@ -2468,6 +2469,7 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
2468restart_loop: 2469restart_loop:
2469 while (pending_scrq(adapter, scrq)) { 2470 while (pending_scrq(adapter, scrq)) {
2470 unsigned int pool = scrq->pool_index; 2471 unsigned int pool = scrq->pool_index;
2472 int num_entries = 0;
2471 2473
2472 next = ibmvnic_next_scrq(adapter, scrq); 2474 next = ibmvnic_next_scrq(adapter, scrq);
2473 for (i = 0; i < next->tx_comp.num_comps; i++) { 2475 for (i = 0; i < next->tx_comp.num_comps; i++) {
@@ -2498,6 +2500,8 @@ restart_loop:
2498 txbuff->skb = NULL; 2500 txbuff->skb = NULL;
2499 } 2501 }
2500 2502
2503 num_entries += txbuff->num_entries;
2504
2501 adapter->tx_pool[pool].free_map[adapter->tx_pool[pool]. 2505 adapter->tx_pool[pool].free_map[adapter->tx_pool[pool].
2502 producer_index] = index; 2506 producer_index] = index;
2503 adapter->tx_pool[pool].producer_index = 2507 adapter->tx_pool[pool].producer_index =
@@ -2507,7 +2511,7 @@ restart_loop:
2507 /* remove tx_comp scrq*/ 2511 /* remove tx_comp scrq*/
2508 next->tx_comp.first = 0; 2512 next->tx_comp.first = 0;
2509 2513
2510 if (atomic_sub_return(next->tx_comp.num_comps, &scrq->used) <= 2514 if (atomic_sub_return(num_entries, &scrq->used) <=
2511 (adapter->req_tx_entries_per_subcrq / 2) && 2515 (adapter->req_tx_entries_per_subcrq / 2) &&
2512 __netif_subqueue_stopped(adapter->netdev, 2516 __netif_subqueue_stopped(adapter->netdev,
2513 scrq->pool_index)) { 2517 scrq->pool_index)) {
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
index fe21a6e2ddae..2f51458ccdc3 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -909,6 +909,7 @@ struct ibmvnic_tx_buff {
909 union sub_crq indir_arr[6]; 909 union sub_crq indir_arr[6];
910 u8 hdr_data[140]; 910 u8 hdr_data[140];
911 dma_addr_t indir_dma; 911 dma_addr_t indir_dma;
912 int num_entries;
912}; 913};
913 914
914struct ibmvnic_tx_pool { 915struct ibmvnic_tx_pool {