[dpdk-dev] [PATCH 07/11] ethdev: add lock to port allocation check
Gaëtan Rivet
gaetan.rivet at 6wind.com
Wed May 9 14:21:17 CEST 2018
Hi,
On Wed, May 09, 2018 at 11:43:33AM +0200, Thomas Monjalon wrote:
> From: Matan Azrad <matan at mellanox.com>
>
> When comparing the port name, there can be a race condition with
> a thread allocating a new port and writing the name at the same time.
> It can lead to match with a partial name by error.
>
> The check of the port is now considered as a critical section
> protected with locks.
>
> This fix will be even more required for multi-process when the
> port availability will rely only on the name, in a following patch.
>
> Fixes: 84934303a17c ("ethdev: synchronize port allocation")
> Cc: stable at dpdk.org
>
> Signed-off-by: Matan Azrad <matan at mellanox.com>
> Acked-by: Thomas Monjalon <thomas at monjalon.net>
> ---
> lib/librte_ethdev/rte_ethdev.c | 22 +++++++++++++++++++---
> 1 file changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
> index ae86d0ba7..357be2dca 100644
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> @@ -227,8 +227,8 @@ rte_eth_dev_shared_data_prepare(void)
> rte_spinlock_unlock(&rte_eth_shared_data_lock);
> }
>
> -struct rte_eth_dev *
> -rte_eth_dev_allocated(const char *name)
> +static struct rte_eth_dev *
> +rte_eth_dev_allocated_lock_free(const char *name)
A suggestion about the naming here.
Reading subsequent patches, we can see this function being used during
ethdev allocation routines. The _lock_free suffix is a little
misleading, as for an instant one can think that there is something
being freed about an allocated ethdev lock.
I would suggest
* rte_eth_dev_allocated_nolock
or
* rte_eth_dev_allocated_lockless
(or even rte_eth_lockless_dev_allocated)
instead.
> {
> unsigned i;
>
> @@ -240,6 +240,22 @@ rte_eth_dev_allocated(const char *name)
> return NULL;
> }
>
> +struct rte_eth_dev *
> +rte_eth_dev_allocated(const char *name)
> +{
> + struct rte_eth_dev *ethdev;
> +
> + rte_eth_dev_shared_data_prepare();
> +
> + rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
> +
> + ethdev = rte_eth_dev_allocated_lock_free(name);
> +
> + rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
> +
> + return ethdev;
> +}
> +
> static uint16_t
> rte_eth_dev_find_free_port(void)
> {
> @@ -286,7 +302,7 @@ rte_eth_dev_allocate(const char *name)
> goto unlock;
> }
>
> - if (rte_eth_dev_allocated(name) != NULL) {
> + if (rte_eth_dev_allocated_lock_free(name) != NULL) {
> ethdev_log(ERR,
> "Ethernet Device with name %s already allocated!",
> name);
> --
> 2.16.2
>
--
Gaëtan Rivet
6WIND
More information about the dev
mailing list