All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Burakov, Anatoly" <anatoly.burakov@intel.com>
To: Jianfeng Tan <jianfeng.tan@intel.com>, dev@dpdk.org
Cc: thomas@monjalon.net
Subject: Re: [PATCH v3 2/5] bus/vdev: add lock on vdev device list
Date: Fri, 20 Apr 2018 09:26:06 +0100	[thread overview]
Message-ID: <fd0afef8-9c14-934e-23a6-7413cc086e4f@intel.com> (raw)
In-Reply-To: <1524156618-81402-3-git-send-email-jianfeng.tan@intel.com>

On 19-Apr-18 5:50 PM, Jianfeng Tan wrote:
> As we could add virtual devices from different threads now, we
> add a spin lock to protect the vdev device list.
> 
> Suggested-by: Anatoly Burakov <anatoly.burakov@intel.com>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Reviewed-by: Qi Zhang <qi.z.zhang@intel.com>
> ---

<...>

> +/* The caller shall be responsible for thread-safe */
>   static struct rte_vdev_device *
>   find_vdev(const char *name)
>   {
> @@ -203,10 +206,6 @@ rte_vdev_init(const char *name, const char *args)
>   	if (name == NULL)
>   		return -EINVAL;
>   
> -	dev = find_vdev(name);
> -	if (dev)
> -		return -EEXIST;
> -
>   	devargs = alloc_devargs(name, args);
>   	if (!devargs)
>   		return -ENOMEM;
> @@ -221,16 +220,28 @@ rte_vdev_init(const char *name, const char *args)
>   	dev->device.numa_node = SOCKET_ID_ANY;
>   	dev->device.name = devargs->name;
>   
> +	rte_spinlock_lock(&vdev_device_list_lock);
> +	if (find_vdev(name)) {
> +		rte_spinlock_unlock(&vdev_device_list_lock);
> +		ret = -EEXIST;
> +		goto fail;
> +	}
> +	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
> +	rte_spinlock_unlock(&vdev_device_list_lock);
> +

I wonder if is possible to just leave the tailq locked until you either 
insert the device into tailq, or figure out that it's not possible? 
Seems like doing two locks here is unnecessary, unless 
vdev_probe_all_drivers needs this tailq unlocked...

>   	ret = vdev_probe_all_drivers(dev);
>   	if (ret) {
>   		if (ret > 0)
>   			VDEV_LOG(ERR, "no driver found for %s\n", name);
> +		/* If fails, remove it from vdev list */
> +		rte_spinlock_lock(&vdev_device_list_lock);
> +		TAILQ_REMOVE(&vdev_device_list, dev, next);
> +		rte_spinlock_unlock(&vdev_device_list_lock);
>   		goto fail;
>   	}
>   
>   	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
>   
> -	TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
>   	return 0;
>   
>   fail:
> @@ -266,17 +277,25 @@ rte_vdev_uninit(const char *name)
>   	if (name == NULL)
>   		return -EINVAL;
>   
> +	rte_spinlock_lock(&vdev_device_list_lock);
>   	dev = find_vdev(name);
> -	if (!dev)
> +	if (!dev) {
> +		rte_spinlock_unlock(&vdev_device_list_lock);
>   		return -ENOENT;
> +	}
> +	TAILQ_REMOVE(&vdev_device_list, dev, next);
> +	rte_spinlock_unlock(&vdev_device_list_lock);
>   
>   	devargs = dev->device.devargs;
>   
>   	ret = vdev_remove_driver(dev);
> -	if (ret)
> +	if (ret) {
> +		/* If fails, add back to vdev list */
> +		rte_spinlock_lock(&vdev_device_list_lock);
> +		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
> +		rte_spinlock_unlock(&vdev_device_list_lock);
>   		return ret;
> -
> -	TAILQ_REMOVE(&vdev_device_list, dev, next);
> +	}

Same comment here - perhaps keep the lock locked all the way? Maybe a 
good way to ensure you don't miss anything is put most of it in a static 
function, and do

static int vdev_uninit() {
	...
}

static int rte_vdev_uninit() {
	int ret;
	lock();
	ret = vdev_uninit();
	unlock();
	return ret;
}

? In general, it is better to do lock/unlock in one place and not 
disperse lock/unlock calls across various branches.

>   
>   	TAILQ_REMOVE(&devargs_list, devargs, next);
>   
> @@ -314,19 +333,25 @@ vdev_scan(void)
>   		if (devargs->bus != &rte_vdev_bus)
>   			continue;
>   
> -		dev = find_vdev(devargs->name);
> -		if (dev)
> -			continue;
> -
>   		dev = calloc(1, sizeof(*dev));
>   		if (!dev)
>   			return -1;
>   
> +		rte_spinlock_lock(&vdev_device_list_lock);
> +
> +		if (find_vdev(devargs->name)) {
> +			rte_spinlock_unlock(&vdev_device_list_lock);
> +			free(dev);
> +			continue;
> +		}
> +
>   		dev->device.devargs = devargs;
>   		dev->device.numa_node = SOCKET_ID_ANY;
>   		dev->device.name = devargs->name;
>   
>   		TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
> +
> +		rte_spinlock_unlock(&vdev_device_list_lock);
>   	}
>   
>   	return 0;
> @@ -340,6 +365,10 @@ vdev_probe(void)
>   
>   	/* call the init function for each virtual device */
>   	TAILQ_FOREACH(dev, &vdev_device_list, next) {
> +		/* we don't use the vdev lock here, as it's only used in DPDK
> +		 * initialization; and we don't want to hold such a lock when
> +		 * we call each driver probe.
> +		 */
>   
>   		if (dev->device.driver)
>   			continue;
> @@ -360,14 +389,18 @@ vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
>   {
>   	struct rte_vdev_device *dev;
>   
> +	rte_spinlock_lock(&vdev_device_list_lock);
>   	TAILQ_FOREACH(dev, &vdev_device_list, next) {
>   		if (start && &dev->device == start) {
>   			start = NULL;
>   			continue;
>   		}
> -		if (cmp(&dev->device, data) == 0)
> +		if (cmp(&dev->device, data) == 0) {
> +			rte_spinlock_unlock(&vdev_device_list_lock);
>   			return &dev->device;
> +		}
>   	}
> +	rte_spinlock_unlock(&vdev_device_list_lock);
>   	return NULL;

How about

break;
}
unlock();
return dev ? &dev->device : NULL;

? Seems clearer to me.

>   }
>   
> 


-- 
Thanks,
Anatoly

  reply	other threads:[~2018-04-20  8:26 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-04 15:30 [PATCH 0/4] allow procinfo and pdump on eth vdev Jianfeng Tan
2018-03-04 15:30 ` [PATCH 1/4] eal: bring forward multi-process channel init Jianfeng Tan
2018-03-04 15:30 ` [PATCH 2/4] bus/vdev: bus scan by multi-process channel Jianfeng Tan
2018-03-05  9:36   ` Burakov, Anatoly
2018-03-06  0:50     ` Tan, Jianfeng
2018-03-07 14:00   ` Burakov, Anatoly
2018-03-12  3:22     ` Tan, Jianfeng
2018-03-04 15:30 ` [PATCH 3/4] drivers/net: do not allocate rte_eth_dev_data privately Jianfeng Tan
2018-03-06  6:07   ` Matan Azrad
2018-03-06  8:55     ` Tan, Jianfeng
2018-03-07  6:00       ` Matan Azrad
2018-03-07  6:10         ` Matan Azrad
2018-03-12  3:40           ` Tan, Jianfeng
2018-03-04 15:30 ` [PATCH 4/4] drivers/net: share vdev data to secondary process Jianfeng Tan
2018-04-19 16:50 ` [PATCH v3 0/5] allow procinfo and pdump on eth vdev Jianfeng Tan
2018-04-19 16:50   ` [PATCH v3 1/5] eal: bring forward multi-process channel init Jianfeng Tan
2018-04-20  8:16     ` Burakov, Anatoly
2018-04-20 14:08       ` Tan, Jianfeng
2018-04-19 16:50   ` [PATCH v3 2/5] bus/vdev: add lock on vdev device list Jianfeng Tan
2018-04-20  8:26     ` Burakov, Anatoly [this message]
2018-04-20 14:19       ` Tan, Jianfeng
2018-04-20 15:16         ` Burakov, Anatoly
2018-04-20 15:23           ` Tan, Jianfeng
2018-04-19 16:50   ` [PATCH v3 3/5] bus/vdev: bus scan by multi-process channel Jianfeng Tan
2018-04-20  8:41     ` Burakov, Anatoly
2018-04-20 14:28       ` Tan, Jianfeng
2018-04-20 15:19         ` Burakov, Anatoly
2018-04-20 15:32           ` Tan, Jianfeng
2018-04-20 15:39             ` Burakov, Anatoly
2018-04-19 16:50   ` [PATCH v3 4/5] drivers/net: not use private eth dev data Jianfeng Tan
2018-04-19 16:50   ` [PATCH v3 5/5] drivers/net: share vdev data to secondary process Jianfeng Tan
2018-04-20 16:57 ` [PATCH v4 0/5] allow procinfo and pdump on eth vdev Jianfeng Tan
2018-04-20 16:57   ` [PATCH v4 1/5] eal: bring forward multi-process channel init Jianfeng Tan
2018-04-20 16:57   ` [PATCH v4 2/5] bus/vdev: add lock on vdev device list Jianfeng Tan
2018-04-23  9:47     ` Burakov, Anatoly
2018-04-20 16:57   ` [PATCH v4 3/5] bus/vdev: bus scan by multi-process channel Jianfeng Tan
2018-04-23  9:54     ` Burakov, Anatoly
2018-04-24  5:22       ` Tan, Jianfeng
2018-04-20 16:57   ` [PATCH v4 4/5] drivers/net: not use private eth dev data Jianfeng Tan
2018-04-20 16:57   ` [PATCH v4 5/5] drivers/net: share vdev data to secondary process Jianfeng Tan
2018-04-24  5:51 ` [PATCH v5 0/5] allow procinfo and pdump on eth vdev Jianfeng Tan
2018-04-24  5:51   ` [PATCH v5 1/5] eal: bring forward multi-process channel init Jianfeng Tan
2018-04-24  5:51   ` [PATCH v5 2/5] bus/vdev: add lock on vdev device list Jianfeng Tan
2018-04-24  5:51   ` [PATCH v5 3/5] bus/vdev: bus scan by multi-process channel Jianfeng Tan
2018-04-24 10:09     ` Thomas Monjalon
2018-04-24  5:51   ` [PATCH v5 4/5] drivers/net: not use private eth dev data Jianfeng Tan
2018-04-24  5:51   ` [PATCH v5 5/5] drivers/net: share vdev data to secondary process Jianfeng Tan
2018-04-24 10:32   ` [PATCH v5 0/5] allow procinfo and pdump on eth vdev Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fd0afef8-9c14-934e-23a6-7413cc086e4f@intel.com \
    --to=anatoly.burakov@intel.com \
    --cc=dev@dpdk.org \
    --cc=jianfeng.tan@intel.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.