[12/20] net/pcap: release port upon close

Message ID 20200913220711.3768597-13-thomas@monjalon.net (mailing list archive)
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers
Series cleanup ethdev close operation |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Thomas Monjalon Sept. 13, 2020, 10:07 p.m. UTC
  The flag RTE_ETH_DEV_CLOSE_REMOVE is set so all port resources
can be freed by rte_eth_dev_close().

Freeing of private port resources is moved
from the ".remove(device)" to the ".dev_close(port)" operation.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 drivers/net/pcap/rte_eth_pcap.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)
  

Comments

Ferruh Yigit Sept. 23, 2020, 4:44 p.m. UTC | #1
On 9/13/2020 11:07 PM, Thomas Monjalon wrote:
> The flag RTE_ETH_DEV_CLOSE_REMOVE is set so all port resources
> can be freed by rte_eth_dev_close().
> 
> Freeing of private port resources is moved
> from the ".remove(device)" to the ".dev_close(port)" operation.
> 
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
>   drivers/net/pcap/rte_eth_pcap.c | 29 ++++++++++++++---------------
>   1 file changed, 14 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
> index 76e704a65a..a946fa9a1a 100644
> --- a/drivers/net/pcap/rte_eth_pcap.c
> +++ b/drivers/net/pcap/rte_eth_pcap.c
> @@ -734,6 +734,12 @@ eth_dev_close(struct rte_eth_dev *dev)
>   	unsigned int i;
>   	struct pmd_internals *internals = dev->data->dev_private;
>   
> +	if (internals == NULL)
> +		return 0;

Not sure if this check needed, can 'internals' be null at this stage?

But perhaps need to add 'RTE_PROC_PRIMARY' check.

> +
> +	PMD_LOG(INFO, "Closing pcap ethdev on NUMA socket %d",
> +			rte_socket_id());
> +
>   	/* Device wide flag, but cleanup must be performed per queue. */
>   	if (internals->infinite_rx) {
>   		for (i = 0; i < dev->data->nb_rx_queues; i++) {
> @@ -748,6 +754,12 @@ eth_dev_close(struct rte_eth_dev *dev)
>   		}
>   	}
>   
> +	rte_free(dev->process_private);
> +

Can we move freeing 'process_private' to 'rte_eth_dev_release_port()'
  
Thomas Monjalon Sept. 23, 2020, 8:44 p.m. UTC | #2
23/09/2020 18:44, Ferruh Yigit:
> On 9/13/2020 11:07 PM, Thomas Monjalon wrote:
> > The flag RTE_ETH_DEV_CLOSE_REMOVE is set so all port resources
> > can be freed by rte_eth_dev_close().
> > 
> > Freeing of private port resources is moved
> > from the ".remove(device)" to the ".dev_close(port)" operation.
> > 
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> >   drivers/net/pcap/rte_eth_pcap.c | 29 ++++++++++++++---------------
> >   1 file changed, 14 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
> > index 76e704a65a..a946fa9a1a 100644
> > --- a/drivers/net/pcap/rte_eth_pcap.c
> > +++ b/drivers/net/pcap/rte_eth_pcap.c
> > @@ -734,6 +734,12 @@ eth_dev_close(struct rte_eth_dev *dev)
> >   	unsigned int i;
> >   	struct pmd_internals *internals = dev->data->dev_private;
> >   
> > +	if (internals == NULL)
> > +		return 0;
> 
> Not sure if this check needed, can 'internals' be null at this stage?

I think yes we need to protect against a double close.

> But perhaps need to add 'RTE_PROC_PRIMARY' check.

Yes but that's not the goal of this patch.

> > +	rte_free(dev->process_private);
> 
> Can we move freeing 'process_private' to 'rte_eth_dev_release_port()'

Yes we could.
  
Ferruh Yigit Sept. 24, 2020, 11:56 a.m. UTC | #3
On 9/23/2020 9:44 PM, Thomas Monjalon wrote:
> 23/09/2020 18:44, Ferruh Yigit:
>> On 9/13/2020 11:07 PM, Thomas Monjalon wrote:
>>> The flag RTE_ETH_DEV_CLOSE_REMOVE is set so all port resources
>>> can be freed by rte_eth_dev_close().
>>>
>>> Freeing of private port resources is moved
>>> from the ".remove(device)" to the ".dev_close(port)" operation.
>>>
>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>>> ---
>>>    drivers/net/pcap/rte_eth_pcap.c | 29 ++++++++++++++---------------
>>>    1 file changed, 14 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
>>> index 76e704a65a..a946fa9a1a 100644
>>> --- a/drivers/net/pcap/rte_eth_pcap.c
>>> +++ b/drivers/net/pcap/rte_eth_pcap.c
>>> @@ -734,6 +734,12 @@ eth_dev_close(struct rte_eth_dev *dev)
>>>    	unsigned int i;
>>>    	struct pmd_internals *internals = dev->data->dev_private;
>>>    
>>> +	if (internals == NULL)
>>> +		return 0;
>>
>> Not sure if this check needed, can 'internals' be null at this stage?
> 
> I think yes we need to protect against a double close.
 >

'eth_dev_close()' can be called by 'pmd_pcap_remove()' or 
'rte_eth_dev_close()' both should be blocked to call 'eth_dev_close()' 
after first close.

And same thing for all PMDs, if they don't need, this one also shouldn't 
need.

> 
>> But perhaps need to add 'RTE_PROC_PRIMARY' check.
> 
> Yes but that's not the goal of this patch.
> 

Yes, the check should be there already, but now more stuff added to 
close dev_ops, and calling it from secondary will cause problem. Since 
you are already here, I think would be nice to add it.


>>> +	rte_free(dev->process_private);
>>
>> Can we move freeing 'process_private' to 'rte_eth_dev_release_port()'
> 
> Yes we could.
> 
>
  

Patch

diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index 76e704a65a..a946fa9a1a 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -734,6 +734,12 @@  eth_dev_close(struct rte_eth_dev *dev)
 	unsigned int i;
 	struct pmd_internals *internals = dev->data->dev_private;
 
+	if (internals == NULL)
+		return 0;
+
+	PMD_LOG(INFO, "Closing pcap ethdev on NUMA socket %d",
+			rte_socket_id());
+
 	/* Device wide flag, but cleanup must be performed per queue. */
 	if (internals->infinite_rx) {
 		for (i = 0; i < dev->data->nb_rx_queues; i++) {
@@ -748,6 +754,12 @@  eth_dev_close(struct rte_eth_dev *dev)
 		}
 	}
 
+	rte_free(dev->process_private);
+
+	if (internals->phy_mac == 0)
+		/* not dynamically allocated, must not be freed */
+		dev->data->mac_addrs = NULL;
+
 	return 0;
 }
 
@@ -1322,6 +1334,7 @@  eth_from_pcaps(struct rte_vdev_device *vdev,
 	else
 		eth_dev->tx_pkt_burst = eth_tx_drop;
 
+	eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
 	rte_eth_dev_probing_finish(eth_dev);
 	return 0;
 }
@@ -1544,30 +1557,16 @@  pmd_pcap_probe(struct rte_vdev_device *dev)
 static int
 pmd_pcap_remove(struct rte_vdev_device *dev)
 {
-	struct pmd_internals *internals = NULL;
 	struct rte_eth_dev *eth_dev = NULL;
 
-	PMD_LOG(INFO, "Closing pcap ethdev on numa socket %d",
-			rte_socket_id());
-
 	if (!dev)
 		return -1;
 
-	/* reserve an ethdev entry */
 	eth_dev = rte_eth_dev_allocated(rte_vdev_device_name(dev));
 	if (eth_dev == NULL)
-		return -1;
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		internals = eth_dev->data->dev_private;
-		if (internals != NULL && internals->phy_mac == 0)
-			/* not dynamically allocated, must not be freed */
-			eth_dev->data->mac_addrs = NULL;
-	}
+		return 0; /* port already released */
 
 	eth_dev_close(eth_dev);
-
-	rte_free(eth_dev->process_private);
 	rte_eth_dev_release_port(eth_dev);
 
 	return 0;