[v2,2/4] net/virtio: improve queue init error path

Message ID 20210315151957.360530-3-maxime.coquelin@redhat.com (mailing list archive)
State Superseded, archived
Delegated to: Maxime Coquelin
Headers
Series net/virtio: make virtqueue struct cache-friendly |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Maxime Coquelin March 15, 2021, 3:19 p.m. UTC
  This patch improves the error path of virtio_init_queue(),
by cleaning in reversing order all resources that have
been allocated.

Suggested-by: Chenbo Xia <chenbo.xia@intel.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_ethdev.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)
  

Comments

David Marchand March 15, 2021, 3:38 p.m. UTC | #1
On Mon, Mar 15, 2021 at 4:20 PM Maxime Coquelin
<maxime.coquelin@redhat.com> wrote:
> @@ -604,15 +604,22 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t queue_idx)
>
>         if (VIRTIO_OPS(hw)->setup_queue(hw, vq) < 0) {
>                 PMD_INIT_LOG(ERR, "setup_queue failed");
> -               return -EINVAL;
> +               ret = -EINVAL;
> +               goto clean_vq;
>         }
>
>         return 0;
>
> -fail_q_alloc:
> -       rte_free(sw_ring);
> +clean_vq:
> +       hw->cvq = NULL;
> +
> +       if (sw_ring)
> +               rte_free(sw_ring);

Nit: rte_free handles NULL fine, you can remove the test, the same way
it was done before.

> +free_hdr_mz:
>         rte_memzone_free(hdr_mz);
> +free_mz:
>         rte_memzone_free(mz);
> +free_vq:
>         rte_free(vq);
>
>         return ret;
  
Maxime Coquelin March 15, 2021, 3:41 p.m. UTC | #2
On 3/15/21 4:38 PM, David Marchand wrote:
> On Mon, Mar 15, 2021 at 4:20 PM Maxime Coquelin
> <maxime.coquelin@redhat.com> wrote:
>> @@ -604,15 +604,22 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t queue_idx)
>>
>>         if (VIRTIO_OPS(hw)->setup_queue(hw, vq) < 0) {
>>                 PMD_INIT_LOG(ERR, "setup_queue failed");
>> -               return -EINVAL;
>> +               ret = -EINVAL;
>> +               goto clean_vq;
>>         }
>>
>>         return 0;
>>
>> -fail_q_alloc:
>> -       rte_free(sw_ring);
>> +clean_vq:
>> +       hw->cvq = NULL;
>> +
>> +       if (sw_ring)
>> +               rte_free(sw_ring);
> 
> Nit: rte_free handles NULL fine, you can remove the test, the same way
> it was done before.

The API doc indeed specifies the NULL case, I'll remove it in v3.

>> +free_hdr_mz:
>>         rte_memzone_free(hdr_mz);
>> +free_mz:
>>         rte_memzone_free(mz);
>> +free_vq:
>>         rte_free(vq);
>>
>>         return ret;
> 

Thanks,
Maxime
  

Patch

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index af090fdf9c..65ad71f1a6 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -507,7 +507,7 @@  virtio_init_queue(struct rte_eth_dev *dev, uint16_t queue_idx)
 			mz = rte_memzone_lookup(vq_name);
 		if (mz == NULL) {
 			ret = -ENOMEM;
-			goto fail_q_alloc;
+			goto free_vq;
 		}
 	}
 
@@ -533,7 +533,7 @@  virtio_init_queue(struct rte_eth_dev *dev, uint16_t queue_idx)
 				hdr_mz = rte_memzone_lookup(vq_hdr_name);
 			if (hdr_mz == NULL) {
 				ret = -ENOMEM;
-				goto fail_q_alloc;
+				goto free_mz;
 			}
 		}
 	}
@@ -547,7 +547,7 @@  virtio_init_queue(struct rte_eth_dev *dev, uint16_t queue_idx)
 		if (!sw_ring) {
 			PMD_INIT_LOG(ERR, "can not allocate RX soft ring");
 			ret = -ENOMEM;
-			goto fail_q_alloc;
+			goto free_hdr_mz;
 		}
 
 		vq->sw_ring = sw_ring;
@@ -604,15 +604,22 @@  virtio_init_queue(struct rte_eth_dev *dev, uint16_t queue_idx)
 
 	if (VIRTIO_OPS(hw)->setup_queue(hw, vq) < 0) {
 		PMD_INIT_LOG(ERR, "setup_queue failed");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto clean_vq;
 	}
 
 	return 0;
 
-fail_q_alloc:
-	rte_free(sw_ring);
+clean_vq:
+	hw->cvq = NULL;
+
+	if (sw_ring)
+		rte_free(sw_ring);
+free_hdr_mz:
 	rte_memzone_free(hdr_mz);
+free_mz:
 	rte_memzone_free(mz);
+free_vq:
 	rte_free(vq);
 
 	return ret;