net: hns3: bugfix for buffer not free problem during resetting
When hns3_get_ring_config()/hns3_queue_to_ring()/
hns3_get_vector_ring_chain() failed during resetting, the allocated
memory has not been freed before these three functions return. So
this patch adds error handler in these functions to fix it.
Fixes: 76ad4f0ee7 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									ece4bf46e9
								
							
						
					
					
						commit
						73b907a083
					
				| @ -2727,7 +2727,7 @@ static int hns3_get_vector_ring_chain(struct hns3_enet_tqp_vector *tqp_vector, | |||||||
| 			chain = devm_kzalloc(&pdev->dev, sizeof(*chain), | 			chain = devm_kzalloc(&pdev->dev, sizeof(*chain), | ||||||
| 					     GFP_KERNEL); | 					     GFP_KERNEL); | ||||||
| 			if (!chain) | 			if (!chain) | ||||||
| 				return -ENOMEM; | 				goto err_free_chain; | ||||||
| 
 | 
 | ||||||
| 			cur_chain->next = chain; | 			cur_chain->next = chain; | ||||||
| 			chain->tqp_index = tx_ring->tqp->tqp_index; | 			chain->tqp_index = tx_ring->tqp->tqp_index; | ||||||
| @ -2757,7 +2757,7 @@ static int hns3_get_vector_ring_chain(struct hns3_enet_tqp_vector *tqp_vector, | |||||||
| 	while (rx_ring) { | 	while (rx_ring) { | ||||||
| 		chain = devm_kzalloc(&pdev->dev, sizeof(*chain), GFP_KERNEL); | 		chain = devm_kzalloc(&pdev->dev, sizeof(*chain), GFP_KERNEL); | ||||||
| 		if (!chain) | 		if (!chain) | ||||||
| 			return -ENOMEM; | 			goto err_free_chain; | ||||||
| 
 | 
 | ||||||
| 		cur_chain->next = chain; | 		cur_chain->next = chain; | ||||||
| 		chain->tqp_index = rx_ring->tqp->tqp_index; | 		chain->tqp_index = rx_ring->tqp->tqp_index; | ||||||
| @ -2772,6 +2772,16 @@ static int hns3_get_vector_ring_chain(struct hns3_enet_tqp_vector *tqp_vector, | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  | 
 | ||||||
|  | err_free_chain: | ||||||
|  | 	cur_chain = head->next; | ||||||
|  | 	while (cur_chain) { | ||||||
|  | 		chain = cur_chain->next; | ||||||
|  | 		devm_kfree(&pdev->dev, chain); | ||||||
|  | 		cur_chain = chain; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return -ENOMEM; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void hns3_free_vector_ring_chain(struct hns3_enet_tqp_vector *tqp_vector, | static void hns3_free_vector_ring_chain(struct hns3_enet_tqp_vector *tqp_vector, | ||||||
| @ -3037,8 +3047,10 @@ static int hns3_queue_to_ring(struct hnae3_queue *tqp, | |||||||
| 		return ret; | 		return ret; | ||||||
| 
 | 
 | ||||||
| 	ret = hns3_ring_get_cfg(tqp, priv, HNAE3_RING_TYPE_RX); | 	ret = hns3_ring_get_cfg(tqp, priv, HNAE3_RING_TYPE_RX); | ||||||
| 	if (ret) | 	if (ret) { | ||||||
|  | 		devm_kfree(priv->dev, priv->ring_data[tqp->tqp_index].ring); | ||||||
| 		return ret; | 		return ret; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| @ -3065,6 +3077,12 @@ static int hns3_get_ring_config(struct hns3_nic_priv *priv) | |||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| err: | err: | ||||||
|  | 	while (i--) { | ||||||
|  | 		devm_kfree(priv->dev, priv->ring_data[i].ring); | ||||||
|  | 		devm_kfree(priv->dev, | ||||||
|  | 			   priv->ring_data[i + h->kinfo.num_tqps].ring); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	devm_kfree(&pdev->dev, priv->ring_data); | 	devm_kfree(&pdev->dev, priv->ring_data); | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user