 7b31c2e9ed
			
		
	
	7b31c2e9ed
	
	
	
		
			
			Backport Russell King's series [1] net: mvneta: reduce size of TSO header allocation to pending-5.15 to fix random crashes on Turris Omnia. This also backports two patches that are dependencies to this series: net: mvneta: Delete unused variable net: mvneta: fix potential double-frees in mvneta_txq_sw_deinit() [1] https://lore.kernel.org/netdev/ZCsbJ4nG+So%2Fn9qY@shell.armlinux.org.uk/ Signed-off-by: Marek Behún <kabel@kernel.org> Signed-off-by: Christian Lamparter <chunkeey@gmail.com> (squashed)
		
			
				
	
	
		
			112 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From d6d80269cf5c79f9dfe7d69f8b41a72015c89748 Mon Sep 17 00:00:00 2001
 | |
| From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
 | |
| Date: Mon, 3 Apr 2023 19:30:20 +0100
 | |
| Subject: [PATCH 1/5] net: mvneta: fix transmit path dma-unmapping on error
 | |
| 
 | |
| The transmit code assumes that the transmit descriptors that are used
 | |
| begin with the first descriptor in the ring, but this may not be the
 | |
| case. Fix this by providing a new function that dma-unmaps a range of
 | |
| numbered descriptor entries, and use that to do the unmapping.
 | |
| 
 | |
| Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
 | |
| ---
 | |
|  drivers/net/ethernet/marvell/mvneta.c | 53 +++++++++++++++++----------
 | |
|  1 file changed, 33 insertions(+), 20 deletions(-)
 | |
| 
 | |
| --- a/drivers/net/ethernet/marvell/mvneta.c
 | |
| +++ b/drivers/net/ethernet/marvell/mvneta.c
 | |
| @@ -2647,14 +2647,40 @@ mvneta_tso_put_data(struct net_device *d
 | |
|  	return 0;
 | |
|  }
 | |
|  
 | |
| +static void mvneta_release_descs(struct mvneta_port *pp,
 | |
| +				 struct mvneta_tx_queue *txq,
 | |
| +				 int first, int num)
 | |
| +{
 | |
| +	int desc_idx, i;
 | |
| +
 | |
| +	desc_idx = first + num;
 | |
| +	if (desc_idx >= txq->size)
 | |
| +		desc_idx -= txq->size;
 | |
| +
 | |
| +	for (i = num; i >= 0; i--) {
 | |
| +		struct mvneta_tx_desc *tx_desc = txq->descs + desc_idx;
 | |
| +
 | |
| +		if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr))
 | |
| +			dma_unmap_single(pp->dev->dev.parent,
 | |
| +					 tx_desc->buf_phys_addr,
 | |
| +					 tx_desc->data_size,
 | |
| +					 DMA_TO_DEVICE);
 | |
| +
 | |
| +		mvneta_txq_desc_put(txq);
 | |
| +
 | |
| +		if (desc_idx == 0)
 | |
| +			desc_idx = txq->size;
 | |
| +		desc_idx -= 1;
 | |
| +	}
 | |
| +}
 | |
| +
 | |
|  static int mvneta_tx_tso(struct sk_buff *skb, struct net_device *dev,
 | |
|  			 struct mvneta_tx_queue *txq)
 | |
|  {
 | |
|  	int hdr_len, total_len, data_left;
 | |
| -	int desc_count = 0;
 | |
| +	int first_desc, desc_count = 0;
 | |
|  	struct mvneta_port *pp = netdev_priv(dev);
 | |
|  	struct tso_t tso;
 | |
| -	int i;
 | |
|  
 | |
|  	/* Count needed descriptors */
 | |
|  	if ((txq->count + tso_count_descs(skb)) >= txq->size)
 | |
| @@ -2665,6 +2691,8 @@ static int mvneta_tx_tso(struct sk_buff
 | |
|  		return 0;
 | |
|  	}
 | |
|  
 | |
| +	first_desc = txq->txq_put_index;
 | |
| +
 | |
|  	/* Initialize the TSO handler, and prepare the first payload */
 | |
|  	hdr_len = tso_start(skb, &tso);
 | |
|  
 | |
| @@ -2705,15 +2733,7 @@ err_release:
 | |
|  	/* Release all used data descriptors; header descriptors must not
 | |
|  	 * be DMA-unmapped.
 | |
|  	 */
 | |
| -	for (i = desc_count - 1; i >= 0; i--) {
 | |
| -		struct mvneta_tx_desc *tx_desc = txq->descs + i;
 | |
| -		if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr))
 | |
| -			dma_unmap_single(pp->dev->dev.parent,
 | |
| -					 tx_desc->buf_phys_addr,
 | |
| -					 tx_desc->data_size,
 | |
| -					 DMA_TO_DEVICE);
 | |
| -		mvneta_txq_desc_put(txq);
 | |
| -	}
 | |
| +	mvneta_release_descs(pp, txq, first_desc, desc_count - 1);
 | |
|  	return 0;
 | |
|  }
 | |
|  
 | |
| @@ -2723,6 +2743,7 @@ static int mvneta_tx_frag_process(struct
 | |
|  {
 | |
|  	struct mvneta_tx_desc *tx_desc;
 | |
|  	int i, nr_frags = skb_shinfo(skb)->nr_frags;
 | |
| +	int first_desc = txq->txq_put_index;
 | |
|  
 | |
|  	for (i = 0; i < nr_frags; i++) {
 | |
|  		struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
 | |
| @@ -2761,15 +2782,7 @@ error:
 | |
|  	/* Release all descriptors that were used to map fragments of
 | |
|  	 * this packet, as well as the corresponding DMA mappings
 | |
|  	 */
 | |
| -	for (i = i - 1; i >= 0; i--) {
 | |
| -		tx_desc = txq->descs + i;
 | |
| -		dma_unmap_single(pp->dev->dev.parent,
 | |
| -				 tx_desc->buf_phys_addr,
 | |
| -				 tx_desc->data_size,
 | |
| -				 DMA_TO_DEVICE);
 | |
| -		mvneta_txq_desc_put(txq);
 | |
| -	}
 | |
| -
 | |
| +	mvneta_release_descs(pp, txq, first_desc, i - 1);
 | |
|  	return -ENOMEM;
 | |
|  }
 | |
|  
 |