All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines
@ 2018-03-15 16:02 Thomas Falcon
  2018-03-15 16:02 ` [PATCH net-next v3 1/7] ibmvnic: Generalize TX pool structure Thomas Falcon
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Thomas Falcon @ 2018-03-15 16:02 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, davem, Thomas Falcon

This patch restructures the TX pool data structure and provides a
separate TX pool array for TSO transmissions. This is already used
in some way due to our unique DMA situation, namely that we cannot
use single DMA mappings for packet data. Previously, both buffer
arrays used the same pool entry. This restructuring allows for
some additional cleanup in the driver code, especially in some
places in the device transmit routine.

In addition, it allows us to more easily track the consumer
and producer indexes of a particular pool. This has been
further improved by better tracking of in-use buffers to
prevent possible data corruption in case an invalid buffer
entry is used.

v3: Forgot to update TX pool cleaning function to handle new data
structures. Included 7th patch for that.

v2: Fix typo in 3/6 commit subject line

Thomas Falcon (7):
  ibmvnic: Generalize TX pool structure
  ibmvnic: Update and clean up reset TX pool routine
  ibmvnic: Update release TX pool routine
  ibmvnic: Update TX pool initialization routine
  ibmvnic: Update TX and TX completion routines
  ibmvnic: Improve TX buffer accounting
  ibmvnic: Update TX pool cleaning routine

 drivers/net/ethernet/ibm/ibmvnic.c | 275 +++++++++++++++++++++----------------
 drivers/net/ethernet/ibm/ibmvnic.h |   8 +-
 2 files changed, 160 insertions(+), 123 deletions(-)

-- 
2.7.5

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH net-next v3 1/7] ibmvnic: Generalize TX pool structure
  2018-03-15 16:02 [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon
@ 2018-03-15 16:02 ` Thomas Falcon
  2018-03-16 16:52   ` David Miller
  2018-03-15 16:02 ` [PATCH net-next v3 2/7] ibmvnic: Update and clean up reset TX pool routine Thomas Falcon
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 11+ messages in thread
From: Thomas Falcon @ 2018-03-15 16:02 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, davem, Thomas Falcon

Remove some unused fields in the structure and include values
describing the individual buffer size and number of buffers in
a TX pool. This allows us to use these fields for TX pool buffer
accounting as opposed to using hard coded values. Finally, split
TSO buffers out and provide an additional TX pool array for TSO.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.h | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
index 099c89d..a2e21b3 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -917,11 +917,9 @@ struct ibmvnic_tx_pool {
 	int *free_map;
 	int consumer_index;
 	int producer_index;
-	wait_queue_head_t ibmvnic_tx_comp_q;
-	struct task_struct *work_thread;
 	struct ibmvnic_long_term_buff long_term_buff;
-	struct ibmvnic_long_term_buff tso_ltb;
-	int tso_index;
+	int num_buffers;
+	int buf_size;
 };
 
 struct ibmvnic_rx_buff {
@@ -1044,6 +1042,7 @@ struct ibmvnic_adapter {
 	u64 promisc;
 
 	struct ibmvnic_tx_pool *tx_pool;
+	struct ibmvnic_tx_pool *tso_pool;
 	struct completion init_done;
 	int init_done_rc;
 
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next v3 2/7] ibmvnic: Update and clean up reset TX pool routine
  2018-03-15 16:02 [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon
  2018-03-15 16:02 ` [PATCH net-next v3 1/7] ibmvnic: Generalize TX pool structure Thomas Falcon
@ 2018-03-15 16:02 ` Thomas Falcon
  2018-03-15 16:02 ` [PATCH net-next v3 3/7] ibmvnic: Update release " Thomas Falcon
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Falcon @ 2018-03-15 16:02 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, davem, Thomas Falcon

Update TX pool reset routine to accommodate new TSO pool array. Introduce
a function that resets one TX pool, and use that function to initialize
each pool in both pool arrays.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c | 45 +++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 9c7d19c..4dc3044 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -557,36 +557,41 @@ static int init_rx_pools(struct net_device *netdev)
 	return 0;
 }
 
+static int reset_one_tx_pool(struct ibmvnic_adapter *adapter,
+			     struct ibmvnic_tx_pool *tx_pool)
+{
+	int rc, i;
+
+	rc = reset_long_term_buff(adapter, &tx_pool->long_term_buff);
+	if (rc)
+		return rc;
+
+	memset(tx_pool->tx_buff, 0,
+	       tx_pool->num_buffers *
+	       sizeof(struct ibmvnic_tx_buff));
+
+	for (i = 0; i < tx_pool->num_buffers; i++)
+		tx_pool->free_map[i] = i;
+
+	tx_pool->consumer_index = 0;
+	tx_pool->producer_index = 0;
+
+	return 0;
+}
+
 static int reset_tx_pools(struct ibmvnic_adapter *adapter)
 {
-	struct ibmvnic_tx_pool *tx_pool;
 	int tx_scrqs;
-	int i, j, rc;
+	int i, rc;
 
 	tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
 	for (i = 0; i < tx_scrqs; i++) {
-		netdev_dbg(adapter->netdev, "Re-setting tx_pool[%d]\n", i);
-
-		tx_pool = &adapter->tx_pool[i];
-
-		rc = reset_long_term_buff(adapter, &tx_pool->long_term_buff);
+		rc = reset_one_tx_pool(adapter, &adapter->tso_pool[i]);
 		if (rc)
 			return rc;
-
-		rc = reset_long_term_buff(adapter, &tx_pool->tso_ltb);
+		rc = reset_one_tx_pool(adapter, &adapter->tx_pool[i]);
 		if (rc)
 			return rc;
-
-		memset(tx_pool->tx_buff, 0,
-		       adapter->req_tx_entries_per_subcrq *
-		       sizeof(struct ibmvnic_tx_buff));
-
-		for (j = 0; j < adapter->req_tx_entries_per_subcrq; j++)
-			tx_pool->free_map[j] = j;
-
-		tx_pool->consumer_index = 0;
-		tx_pool->producer_index = 0;
-		tx_pool->tso_index = 0;
 	}
 
 	return 0;
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next v3 3/7] ibmvnic: Update release TX pool routine
  2018-03-15 16:02 [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon
  2018-03-15 16:02 ` [PATCH net-next v3 1/7] ibmvnic: Generalize TX pool structure Thomas Falcon
  2018-03-15 16:02 ` [PATCH net-next v3 2/7] ibmvnic: Update and clean up reset TX pool routine Thomas Falcon
@ 2018-03-15 16:02 ` Thomas Falcon
  2018-03-15 16:02 ` [PATCH net-next v3 4/7] ibmvnic: Update TX pool initialization routine Thomas Falcon
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Falcon @ 2018-03-15 16:02 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, davem, Thomas Falcon

Introduce function that frees one TX pool.  Use that to release
each pool in both the standard TX pool and TSO pool arrays.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 4dc3044..258d54e 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -608,25 +608,30 @@ static void release_vpd_data(struct ibmvnic_adapter *adapter)
 	adapter->vpd = NULL;
 }
 
+static void release_one_tx_pool(struct ibmvnic_adapter *adapter,
+				struct ibmvnic_tx_pool *tx_pool)
+{
+	kfree(tx_pool->tx_buff);
+	kfree(tx_pool->free_map);
+	free_long_term_buff(adapter, &tx_pool->long_term_buff);
+}
+
 static void release_tx_pools(struct ibmvnic_adapter *adapter)
 {
-	struct ibmvnic_tx_pool *tx_pool;
 	int i;
 
 	if (!adapter->tx_pool)
 		return;
 
 	for (i = 0; i < adapter->num_active_tx_pools; i++) {
-		netdev_dbg(adapter->netdev, "Releasing tx_pool[%d]\n", i);
-		tx_pool = &adapter->tx_pool[i];
-		kfree(tx_pool->tx_buff);
-		free_long_term_buff(adapter, &tx_pool->long_term_buff);
-		free_long_term_buff(adapter, &tx_pool->tso_ltb);
-		kfree(tx_pool->free_map);
+		release_one_tx_pool(adapter, &adapter->tx_pool[i]);
+		release_one_tx_pool(adapter, &adapter->tso_pool[i]);
 	}
 
 	kfree(adapter->tx_pool);
 	adapter->tx_pool = NULL;
+	kfree(adapter->tso_pool);
+	adapter->tso_pool = NULL;
 	adapter->num_active_tx_pools = 0;
 }
 
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next v3 4/7] ibmvnic: Update TX pool initialization routine
  2018-03-15 16:02 [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon
                   ` (2 preceding siblings ...)
  2018-03-15 16:02 ` [PATCH net-next v3 3/7] ibmvnic: Update release " Thomas Falcon
@ 2018-03-15 16:02 ` Thomas Falcon
  2018-03-15 16:02 ` [PATCH net-next v3 5/7] ibmvnic: Update TX and TX completion routines Thomas Falcon
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Falcon @ 2018-03-15 16:02 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, davem, Thomas Falcon

Introduce function that initializes one TX pool. Use that to
create each pool entry in both the standard TX pool and TSO
pool arrays.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c | 90 ++++++++++++++++++++------------------
 1 file changed, 48 insertions(+), 42 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 258d54e..2bb5d56 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -635,13 +635,43 @@ static void release_tx_pools(struct ibmvnic_adapter *adapter)
 	adapter->num_active_tx_pools = 0;
 }
 
+static int init_one_tx_pool(struct net_device *netdev,
+			    struct ibmvnic_tx_pool *tx_pool,
+			    int num_entries, int buf_size)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+	int i;
+
+	tx_pool->tx_buff = kcalloc(num_entries,
+				   sizeof(struct ibmvnic_tx_buff),
+				   GFP_KERNEL);
+	if (!tx_pool->tx_buff)
+		return -1;
+
+	if (alloc_long_term_buff(adapter, &tx_pool->long_term_buff,
+				 num_entries * buf_size))
+		return -1;
+
+	tx_pool->free_map = kcalloc(num_entries, sizeof(int), GFP_KERNEL);
+	if (!tx_pool->free_map)
+		return -1;
+
+	for (i = 0; i < num_entries; i++)
+		tx_pool->free_map[i] = i;
+
+	tx_pool->consumer_index = 0;
+	tx_pool->producer_index = 0;
+	tx_pool->num_buffers = num_entries;
+	tx_pool->buf_size = buf_size;
+
+	return 0;
+}
+
 static int init_tx_pools(struct net_device *netdev)
 {
 	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
-	struct device *dev = &adapter->vdev->dev;
-	struct ibmvnic_tx_pool *tx_pool;
 	int tx_subcrqs;
-	int i, j;
+	int i, rc;
 
 	tx_subcrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
 	adapter->tx_pool = kcalloc(tx_subcrqs,
@@ -649,53 +679,29 @@ static int init_tx_pools(struct net_device *netdev)
 	if (!adapter->tx_pool)
 		return -1;
 
+	adapter->tso_pool = kcalloc(tx_subcrqs,
+				    sizeof(struct ibmvnic_tx_pool), GFP_KERNEL);
+	if (!adapter->tso_pool)
+		return -1;
+
 	adapter->num_active_tx_pools = tx_subcrqs;
 
 	for (i = 0; i < tx_subcrqs; i++) {
-		tx_pool = &adapter->tx_pool[i];
-
-		netdev_dbg(adapter->netdev,
-			   "Initializing tx_pool[%d], %lld buffs\n",
-			   i, adapter->req_tx_entries_per_subcrq);
-
-		tx_pool->tx_buff = kcalloc(adapter->req_tx_entries_per_subcrq,
-					   sizeof(struct ibmvnic_tx_buff),
-					   GFP_KERNEL);
-		if (!tx_pool->tx_buff) {
-			dev_err(dev, "tx pool buffer allocation failed\n");
-			release_tx_pools(adapter);
-			return -1;
-		}
-
-		if (alloc_long_term_buff(adapter, &tx_pool->long_term_buff,
-					 adapter->req_tx_entries_per_subcrq *
-					 (adapter->req_mtu + VLAN_HLEN))) {
-			release_tx_pools(adapter);
-			return -1;
-		}
-
-		/* alloc TSO ltb */
-		if (alloc_long_term_buff(adapter, &tx_pool->tso_ltb,
-					 IBMVNIC_TSO_BUFS *
-					 IBMVNIC_TSO_BUF_SZ)) {
+		rc = init_one_tx_pool(netdev, &adapter->tx_pool[i],
+				      adapter->req_tx_entries_per_subcrq,
+				      adapter->req_mtu + VLAN_HLEN);
+		if (rc) {
 			release_tx_pools(adapter);
-			return -1;
+			return rc;
 		}
 
-		tx_pool->tso_index = 0;
-
-		tx_pool->free_map = kcalloc(adapter->req_tx_entries_per_subcrq,
-					    sizeof(int), GFP_KERNEL);
-		if (!tx_pool->free_map) {
+		init_one_tx_pool(netdev, &adapter->tso_pool[i],
+				 IBMVNIC_TSO_BUFS,
+				 IBMVNIC_TSO_BUF_SZ);
+		if (rc) {
 			release_tx_pools(adapter);
-			return -1;
+			return rc;
 		}
-
-		for (j = 0; j < adapter->req_tx_entries_per_subcrq; j++)
-			tx_pool->free_map[j] = j;
-
-		tx_pool->consumer_index = 0;
-		tx_pool->producer_index = 0;
 	}
 
 	return 0;
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next v3 5/7] ibmvnic: Update TX and TX completion routines
  2018-03-15 16:02 [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon
                   ` (3 preceding siblings ...)
  2018-03-15 16:02 ` [PATCH net-next v3 4/7] ibmvnic: Update TX pool initialization routine Thomas Falcon
@ 2018-03-15 16:02 ` Thomas Falcon
  2018-03-15 16:02 ` [PATCH net-next v3 6/7] ibmvnic: Improve TX buffer accounting Thomas Falcon
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Falcon @ 2018-03-15 16:02 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, davem, Thomas Falcon

Update TX and TX completion routines to account for TX pool
restructuring. TX routine first chooses the pool depending
on whether a packet is GSO or not, then uses it accordingly.

For the completion routine to know which pool it needs to use,
set the most significant bit of the correlator index to one
if the packet uses the TSO pool. On completion, unset the bit
and use the correlator index to release the buffer pool entry.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c | 55 +++++++++++++++++++-------------------
 drivers/net/ethernet/ibm/ibmvnic.h |  1 +
 2 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 2bb5d56..672e922 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1414,8 +1414,11 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
 		ret = NETDEV_TX_OK;
 		goto out;
 	}
+	if (skb_is_gso(skb))
+		tx_pool = &adapter->tso_pool[queue_num];
+	else
+		tx_pool = &adapter->tx_pool[queue_num];
 
-	tx_pool = &adapter->tx_pool[queue_num];
 	tx_scrq = adapter->tx_scrq[queue_num];
 	txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb));
 	handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
@@ -1423,20 +1426,10 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
 
 	index = tx_pool->free_map[tx_pool->consumer_index];
 
-	if (skb_is_gso(skb)) {
-		offset = tx_pool->tso_index * IBMVNIC_TSO_BUF_SZ;
-		dst = tx_pool->tso_ltb.buff + offset;
-		memset(dst, 0, IBMVNIC_TSO_BUF_SZ);
-		data_dma_addr = tx_pool->tso_ltb.addr + offset;
-		tx_pool->tso_index++;
-		if (tx_pool->tso_index == IBMVNIC_TSO_BUFS)
-			tx_pool->tso_index = 0;
-	} else {
-		offset = index * (adapter->req_mtu + VLAN_HLEN);
-		dst = tx_pool->long_term_buff.buff + offset;
-		memset(dst, 0, adapter->req_mtu + VLAN_HLEN);
-		data_dma_addr = tx_pool->long_term_buff.addr + offset;
-	}
+	offset = index * tx_pool->buf_size;
+	dst = tx_pool->long_term_buff.buff + offset;
+	memset(dst, 0, tx_pool->buf_size);
+	data_dma_addr = tx_pool->long_term_buff.addr + offset;
 
 	if (skb_shinfo(skb)->nr_frags) {
 		int cur, i;
@@ -1459,8 +1452,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
 	}
 
 	tx_pool->consumer_index =
-	    (tx_pool->consumer_index + 1) %
-		adapter->req_tx_entries_per_subcrq;
+	    (tx_pool->consumer_index + 1) % tx_pool->num_buffers;
 
 	tx_buff = &tx_pool->tx_buff[index];
 	tx_buff->skb = skb;
@@ -1476,11 +1468,13 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
 	tx_crq.v1.n_crq_elem = 1;
 	tx_crq.v1.n_sge = 1;
 	tx_crq.v1.flags1 = IBMVNIC_TX_COMP_NEEDED;
-	tx_crq.v1.correlator = cpu_to_be32(index);
+
 	if (skb_is_gso(skb))
-		tx_crq.v1.dma_reg = cpu_to_be16(tx_pool->tso_ltb.map_id);
+		tx_crq.v1.correlator =
+			cpu_to_be32(index | IBMVNIC_TSO_POOL_MASK);
 	else
-		tx_crq.v1.dma_reg = cpu_to_be16(tx_pool->long_term_buff.map_id);
+		tx_crq.v1.correlator = cpu_to_be32(index);
+	tx_crq.v1.dma_reg = cpu_to_be16(tx_pool->long_term_buff.map_id);
 	tx_crq.v1.sge_len = cpu_to_be32(skb->len);
 	tx_crq.v1.ioba = cpu_to_be64(data_dma_addr);
 
@@ -1543,7 +1537,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
 
 		if (tx_pool->consumer_index == 0)
 			tx_pool->consumer_index =
-				adapter->req_tx_entries_per_subcrq - 1;
+				tx_pool->num_buffers - 1;
 		else
 			tx_pool->consumer_index--;
 
@@ -2547,6 +2541,7 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
 			       struct ibmvnic_sub_crq_queue *scrq)
 {
 	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_tx_pool *tx_pool;
 	struct ibmvnic_tx_buff *txbuff;
 	union sub_crq *next;
 	int index;
@@ -2566,7 +2561,14 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
 				continue;
 			}
 			index = be32_to_cpu(next->tx_comp.correlators[i]);
-			txbuff = &adapter->tx_pool[pool].tx_buff[index];
+			if (index & IBMVNIC_TSO_POOL_MASK) {
+				tx_pool = &adapter->tso_pool[pool];
+				index &= ~IBMVNIC_TSO_POOL_MASK;
+			} else {
+				tx_pool = &adapter->tx_pool[pool];
+			}
+
+			txbuff = &tx_pool->tx_buff[index];
 
 			for (j = 0; j < IBMVNIC_MAX_FRAGS_PER_CRQ; j++) {
 				if (!txbuff->data_dma[j])
@@ -2589,11 +2591,10 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
 
 			num_entries += txbuff->num_entries;
 
-			adapter->tx_pool[pool].free_map[adapter->tx_pool[pool].
-						     producer_index] = index;
-			adapter->tx_pool[pool].producer_index =
-			    (adapter->tx_pool[pool].producer_index + 1) %
-			    adapter->req_tx_entries_per_subcrq;
+			tx_pool->free_map[tx_pool->producer_index] = index;
+			tx_pool->producer_index =
+				(tx_pool->producer_index + 1) %
+					tx_pool->num_buffers;
 		}
 		/* remove tx_comp scrq*/
 		next->tx_comp.first = 0;
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
index a2e21b3..89efe70 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -43,6 +43,7 @@
 
 #define IBMVNIC_TSO_BUF_SZ	65536
 #define IBMVNIC_TSO_BUFS	64
+#define IBMVNIC_TSO_POOL_MASK	0x80000000
 
 #define IBMVNIC_MAX_LTB_SIZE ((1 << (MAX_ORDER - 1)) * PAGE_SIZE)
 #define IBMVNIC_BUFFER_HLEN 500
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next v3 6/7] ibmvnic: Improve TX buffer accounting
  2018-03-15 16:02 [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon
                   ` (4 preceding siblings ...)
  2018-03-15 16:02 ` [PATCH net-next v3 5/7] ibmvnic: Update TX and TX completion routines Thomas Falcon
@ 2018-03-15 16:02 ` Thomas Falcon
  2018-03-15 16:02 ` [PATCH net-next v3 7/7] ibmvnic: Update TX pool cleaning routine Thomas Falcon
  2018-03-16  0:48 ` [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Falcon @ 2018-03-15 16:02 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, davem, Thomas Falcon

Improve TX pool buffer accounting to prevent the producer
index from overruning the consumer. First, set the next free
index to an invalid value if it is in use. If next buffer
to be consumed is in use, drop the packet.

Finally, if the transmit fails for some other reason, roll
back the consumer index and set the free map entry to its original
value. This should also be done if the DMA map fails.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 672e922..af6f819 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1426,6 +1426,16 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
 
 	index = tx_pool->free_map[tx_pool->consumer_index];
 
+	if (index == IBMVNIC_INVALID_MAP) {
+		dev_kfree_skb_any(skb);
+		tx_send_failed++;
+		tx_dropped++;
+		ret = NETDEV_TX_OK;
+		goto out;
+	}
+
+	tx_pool->free_map[tx_pool->consumer_index] = IBMVNIC_INVALID_MAP;
+
 	offset = index * tx_pool->buf_size;
 	dst = tx_pool->long_term_buff.buff + offset;
 	memset(dst, 0, tx_pool->buf_size);
@@ -1522,7 +1532,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
 			tx_map_failed++;
 			tx_dropped++;
 			ret = NETDEV_TX_OK;
-			goto out;
+			goto tx_err_out;
 		}
 		lpar_rc = send_subcrq_indirect(adapter, handle_array[queue_num],
 					       (u64)tx_buff->indir_dma,
@@ -1534,13 +1544,6 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
 	}
 	if (lpar_rc != H_SUCCESS) {
 		dev_err(dev, "tx failed with code %ld\n", lpar_rc);
-
-		if (tx_pool->consumer_index == 0)
-			tx_pool->consumer_index =
-				tx_pool->num_buffers - 1;
-		else
-			tx_pool->consumer_index--;
-
 		dev_kfree_skb_any(skb);
 		tx_buff->skb = NULL;
 
@@ -1556,7 +1559,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
 		tx_send_failed++;
 		tx_dropped++;
 		ret = NETDEV_TX_OK;
-		goto out;
+		goto tx_err_out;
 	}
 
 	if (atomic_add_return(num_entries, &tx_scrq->used)
@@ -1569,7 +1572,16 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
 	tx_bytes += skb->len;
 	txq->trans_start = jiffies;
 	ret = NETDEV_TX_OK;
+	goto out;
 
+tx_err_out:
+	/* roll back consumer index and map array*/
+	if (tx_pool->consumer_index == 0)
+		tx_pool->consumer_index =
+			tx_pool->num_buffers - 1;
+	else
+		tx_pool->consumer_index--;
+	tx_pool->free_map[tx_pool->consumer_index] = index;
 out:
 	netdev->stats.tx_dropped += tx_dropped;
 	netdev->stats.tx_bytes += tx_bytes;
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next v3 7/7] ibmvnic: Update TX pool cleaning routine
  2018-03-15 16:02 [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon
                   ` (5 preceding siblings ...)
  2018-03-15 16:02 ` [PATCH net-next v3 6/7] ibmvnic: Improve TX buffer accounting Thomas Falcon
@ 2018-03-15 16:02 ` Thomas Falcon
  2018-03-16  0:48 ` [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Falcon @ 2018-03-15 16:02 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, davem, Thomas Falcon

Update routine that cleans up any outstanding transmits that
have not received completions when the device needs to close.
Introduces a helper function that cleans one TX pool to make
code more readable.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c | 40 +++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index af6f819..0e74546 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1128,34 +1128,42 @@ static void clean_rx_pools(struct ibmvnic_adapter *adapter)
 	}
 }
 
-static void clean_tx_pools(struct ibmvnic_adapter *adapter)
+static void clean_one_tx_pool(struct ibmvnic_adapter *adapter,
+			      struct ibmvnic_tx_pool *tx_pool)
 {
-	struct ibmvnic_tx_pool *tx_pool;
 	struct ibmvnic_tx_buff *tx_buff;
 	u64 tx_entries;
+	int i;
+
+	if (!tx_pool && !tx_pool->tx_buff)
+		return;
+
+	tx_entries = adapter->req_tx_entries_per_subcrq;
+
+	for (i = 0; i < tx_entries; i++) {
+		tx_buff = &tx_pool->tx_buff[i];
+		if (tx_buff && tx_buff->skb) {
+			dev_kfree_skb_any(tx_buff->skb);
+			tx_buff->skb = NULL;
+		}
+	}
+}
+
+static void clean_tx_pools(struct ibmvnic_adapter *adapter)
+{
 	int tx_scrqs;
-	int i, j;
+	int i;
 
-	if (!adapter->tx_pool)
+	if (!adapter->tx_pool || !adapter->tso_pool)
 		return;
 
 	tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
-	tx_entries = adapter->req_tx_entries_per_subcrq;
 
 	/* Free any remaining skbs in the tx buffer pools */
 	for (i = 0; i < tx_scrqs; i++) {
-		tx_pool = &adapter->tx_pool[i];
-		if (!tx_pool && !tx_pool->tx_buff)
-			continue;
-
 		netdev_dbg(adapter->netdev, "Cleaning tx_pool[%d]\n", i);
-		for (j = 0; j < tx_entries; j++) {
-			tx_buff = &tx_pool->tx_buff[j];
-			if (tx_buff && tx_buff->skb) {
-				dev_kfree_skb_any(tx_buff->skb);
-				tx_buff->skb = NULL;
-			}
-		}
+		clean_one_tx_pool(adapter, &adapter->tx_pool[i]);
+		clean_one_tx_pool(adapter, &adapter->tso_pool[i]);
 	}
 }
 
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines
  2018-03-15 16:02 [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon
                   ` (6 preceding siblings ...)
  2018-03-15 16:02 ` [PATCH net-next v3 7/7] ibmvnic: Update TX pool cleaning routine Thomas Falcon
@ 2018-03-16  0:48 ` Thomas Falcon
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Falcon @ 2018-03-16  0:48 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, davem

On 03/15/2018 11:02 AM, Thomas Falcon wrote:
> This patch restructures the TX pool data structure and provides a
> separate TX pool array for TSO transmissions. This is already used
> in some way due to our unique DMA situation, namely that we cannot
> use single DMA mappings for packet data. Previously, both buffer
> arrays used the same pool entry. This restructuring allows for
> some additional cleanup in the driver code, especially in some
> places in the device transmit routine.
>
> In addition, it allows us to more easily track the consumer
> and producer indexes of a particular pool. This has been
> further improved by better tracking of in-use buffers to
> prevent possible data corruption in case an invalid buffer
> entry is used.
>
> v3: Forgot to update TX pool cleaning function to handle new data
> structures. Included 7th patch for that.
>
> v2: Fix typo in 3/6 commit subject line
>
> Thomas Falcon (7):
>   ibmvnic: Generalize TX pool structure
>   ibmvnic: Update and clean up reset TX pool routine
>   ibmvnic: Update release TX pool routine
>   ibmvnic: Update TX pool initialization routine
>   ibmvnic: Update TX and TX completion routines
>   ibmvnic: Improve TX buffer accounting
>   ibmvnic: Update TX pool cleaning routine
>
>  drivers/net/ethernet/ibm/ibmvnic.c | 275 +++++++++++++++++++++----------------
>  drivers/net/ethernet/ibm/ibmvnic.h |   8 +-
>  2 files changed, 160 insertions(+), 123 deletions(-)
>
Sorry again, I need to send another version because of a bug in the 7th patch.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next v3 1/7] ibmvnic: Generalize TX pool structure
  2018-03-15 16:02 ` [PATCH net-next v3 1/7] ibmvnic: Generalize TX pool structure Thomas Falcon
@ 2018-03-16 16:52   ` David Miller
  2018-03-16 18:15     ` Thomas Falcon
  0 siblings, 1 reply; 11+ messages in thread
From: David Miller @ 2018-03-16 16:52 UTC (permalink / raw)
  To: tlfalcon; +Cc: netdev, jallen, nfont

From: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Date: Thu, 15 Mar 2018 11:02:37 -0500

> Remove some unused fields in the structure and include values
> describing the individual buffer size and number of buffers in
> a TX pool. This allows us to use these fields for TX pool buffer
> accounting as opposed to using hard coded values. Finally, split
> TSO buffers out and provide an additional TX pool array for TSO.
> 
> Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
 ...
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
> index 099c89d..a2e21b3 100644
> --- a/drivers/net/ethernet/ibm/ibmvnic.h
> +++ b/drivers/net/ethernet/ibm/ibmvnic.h
> @@ -917,11 +917,9 @@ struct ibmvnic_tx_pool {
>  	int *free_map;
>  	int consumer_index;
>  	int producer_index;
> -	wait_queue_head_t ibmvnic_tx_comp_q;
> -	struct task_struct *work_thread;
>  	struct ibmvnic_long_term_buff long_term_buff;
> -	struct ibmvnic_long_term_buff tso_ltb;
> -	int tso_index;
> +	int num_buffers;
> +	int buf_size;
>  };
>  
>  struct ibmvnic_rx_buff {

Thomas, members like tso_ltb are used in the code at this point.

You can't remove it here like this, because it makes your patch series
non-bisectable.  The tree should compile cleanly and work properly at
each stage of your series.

Thank you.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next v3 1/7] ibmvnic: Generalize TX pool structure
  2018-03-16 16:52   ` David Miller
@ 2018-03-16 18:15     ` Thomas Falcon
  0 siblings, 0 replies; 11+ messages in thread
From: Thomas Falcon @ 2018-03-16 18:15 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, jallen, nfont

On 03/16/2018 11:52 AM, David Miller wrote:
> From: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
> Date: Thu, 15 Mar 2018 11:02:37 -0500
>
>> Remove some unused fields in the structure and include values
>> describing the individual buffer size and number of buffers in
>> a TX pool. This allows us to use these fields for TX pool buffer
>> accounting as opposed to using hard coded values. Finally, split
>> TSO buffers out and provide an additional TX pool array for TSO.
>>
>> Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
>  ...
>> diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
>> index 099c89d..a2e21b3 100644
>> --- a/drivers/net/ethernet/ibm/ibmvnic.h
>> +++ b/drivers/net/ethernet/ibm/ibmvnic.h
>> @@ -917,11 +917,9 @@ struct ibmvnic_tx_pool {
>>  	int *free_map;
>>  	int consumer_index;
>>  	int producer_index;
>> -	wait_queue_head_t ibmvnic_tx_comp_q;
>> -	struct task_struct *work_thread;
>>  	struct ibmvnic_long_term_buff long_term_buff;
>> -	struct ibmvnic_long_term_buff tso_ltb;
>> -	int tso_index;
>> +	int num_buffers;
>> +	int buf_size;
>>  };
>>  
>>  struct ibmvnic_rx_buff {
> Thomas, members like tso_ltb are used in the code at this point.
>
> You can't remove it here like this, because it makes your patch series
> non-bisectable.  The tree should compile cleanly and work properly at
> each stage of your series.
>
> Thank you.
>
Thanks for your review, I'll send a reworked series soon.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-03-16 18:15 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-15 16:02 [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon
2018-03-15 16:02 ` [PATCH net-next v3 1/7] ibmvnic: Generalize TX pool structure Thomas Falcon
2018-03-16 16:52   ` David Miller
2018-03-16 18:15     ` Thomas Falcon
2018-03-15 16:02 ` [PATCH net-next v3 2/7] ibmvnic: Update and clean up reset TX pool routine Thomas Falcon
2018-03-15 16:02 ` [PATCH net-next v3 3/7] ibmvnic: Update release " Thomas Falcon
2018-03-15 16:02 ` [PATCH net-next v3 4/7] ibmvnic: Update TX pool initialization routine Thomas Falcon
2018-03-15 16:02 ` [PATCH net-next v3 5/7] ibmvnic: Update TX and TX completion routines Thomas Falcon
2018-03-15 16:02 ` [PATCH net-next v3 6/7] ibmvnic: Improve TX buffer accounting Thomas Falcon
2018-03-15 16:02 ` [PATCH net-next v3 7/7] ibmvnic: Update TX pool cleaning routine Thomas Falcon
2018-03-16  0:48 ` [PATCH net-next v3 0/7] ibmvnic: Update TX pool and TX routines Thomas Falcon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.