[12/20] net/pcap: release port upon close
Checks
Commit Message
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
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()'
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.
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.
>
>
@@ -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;