On 08/08/2016 01:02, "Kavanagh, Mark B" <mark.b.kavan...@intel.com> wrote:
>>
>>Minor comment inline.
>>
>>Acked-by: Ilya Maximets <i.maxim...@samsung.com>
>>
>
>Other than the comment mentioned by Ilya, this LGTM also - thanks again for
>resolving, Daniele.
>
>Acked-by: mark.b.kavan...@intel.com
Thanks for the reviews, I applied this to master
>
>>On 05.08.2016 23:57, Daniele Di Proietto wrote:
>>> netdev_dpdk_vhost_destruct() calls rte_vhost_driver_unregister(), which
>>> can trigger the destroy_device() callback. destroy_device() will try to
>>> take two mutexes already held by netdev_dpdk_vhost_destruct(), causing a
>>> deadlock.
>>>
>>> This problem can be solved by dropping the mutexes before calling
>>> rte_vhost_driver_unregister(). The netdev_dpdk_vhost_destruct() and
>>> construct() call are already serialized by netdev_mutex.
>>>
>>> This commit also makes clear that dev->vhost_id is constant and can be
>>> accessed without taking any mutexes in the lifetime of the devices.
>>>
>>> Fixes: 8d38823bdf8b("netdev-dpdk: fix memory leak")
>>> Reported-by: Ilya Maximets <i.maxim...@samsung.com>
>>> Signed-off-by: Daniele Di Proietto <diproiet...@vmware.com>
>>> ---
>>> lib/netdev-dpdk.c | 34 ++++++++++++++++++++++++----------
>>> 1 file changed, 24 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
>>> index f37ec1c..98bff62 100644
>>> --- a/lib/netdev-dpdk.c
>>> +++ b/lib/netdev-dpdk.c
>>> @@ -355,8 +355,10 @@ struct netdev_dpdk {
>>> /* True if vHost device is 'up' and has been reconfigured at least
>>> once */
>>> bool vhost_reconfigured;
>>>
>>> - /* Identifier used to distinguish vhost devices from each other */
>>> - char vhost_id[PATH_MAX];
>>> + /* Identifier used to distinguish vhost devices from each other. It
>>> does
>>> + * not change during the lifetime of a struct netdev_dpdk. It can be
>>> read
>>> + * without holding any mutex. */
>>> + const char vhost_id[PATH_MAX];
>>>
>>> /* In dpdk_list. */
>>> struct ovs_list list_node OVS_GUARDED_BY(dpdk_mutex);
>>> @@ -846,7 +848,8 @@ netdev_dpdk_vhost_cuse_construct(struct netdev *netdev)
>>> }
>>>
>>> ovs_mutex_lock(&dpdk_mutex);
>>> - strncpy(dev->vhost_id, netdev->name, sizeof(dev->vhost_id));
>>> + strncpy(CONST_CAST(char *, dev->vhost_id), netdev->name,
>>> + sizeof dev->vhost_id);
>>> err = vhost_construct_helper(netdev);
>>> ovs_mutex_unlock(&dpdk_mutex);
>>> return err;
>>> @@ -878,7 +881,7 @@ netdev_dpdk_vhost_user_construct(struct netdev *netdev)
>>> /* Take the name of the vhost-user port and append it to the location
>>> where
>>> * the socket is to be created, then register the socket.
>>> */
>>> - snprintf(dev->vhost_id, sizeof(dev->vhost_id), "%s/%s",
>>> + snprintf(CONST_CAST(char *,dev->vhost_id), sizeof(dev->vhost_id),
>>> "%s/%s",
>>
>>Space between arguments of 'CONST_CAST()' and parenthesized operand of
>>'sizeof'.
Fixed, thanks
>>
>>> vhost_sock_dir, name);
>>>
>>> err = rte_vhost_driver_register(dev->vhost_id, flags);
>>> @@ -938,6 +941,17 @@ netdev_dpdk_destruct(struct netdev *netdev)
>>> ovs_mutex_unlock(&dpdk_mutex);
>>> }
>>>
>>> +/* rte_vhost_driver_unregister() can call back destroy_device(), which will
>>> + * try to acquire 'dpdk_mutex' and possibly 'dev->mutex'. To avoid a
>>> + * deadlock, none of the mutexes must be held while calling this function.
>>> */
>>> +static int
>>> +dpdk_vhost_driver_unregister(struct netdev_dpdk *dev)
>>> + OVS_EXCLUDED(dpdk_mutex)
>>> + OVS_EXCLUDED(dev->mutex)
>>> +{
>>> + return rte_vhost_driver_unregister(dev->vhost_id);
>>> +}
>>> +
>>> static void
>>> netdev_dpdk_vhost_destruct(struct netdev *netdev)
>>> {
>>> @@ -955,12 +969,6 @@ netdev_dpdk_vhost_destruct(struct netdev *netdev)
>>> dev->vhost_id);
>>> }
>>>
>>> - if (rte_vhost_driver_unregister(dev->vhost_id)) {
>>> - VLOG_ERR("Unable to remove vhost-user socket %s", dev->vhost_id);
>>> - } else {
>>> - fatal_signal_remove_file_to_unlink(dev->vhost_id);
>>> - }
>>> -
>>> free(ovsrcu_get_protected(struct ingress_policer *,
>>> &dev->ingress_policer));
>>>
>>> @@ -970,6 +978,12 @@ netdev_dpdk_vhost_destruct(struct netdev *netdev)
>>>
>>> ovs_mutex_unlock(&dev->mutex);
>>> ovs_mutex_unlock(&dpdk_mutex);
>>> +
>>> + if (dpdk_vhost_driver_unregister(dev)) {
>>> + VLOG_ERR("Unable to remove vhost-user socket %s", dev->vhost_id);
>>> + } else {
>>> + fatal_signal_remove_file_to_unlink(dev->vhost_id);
>>> + }
>>> }
>>>
>>> static void
>>>
>>_______________________________________________
>>dev mailing list
>>dev@openvswitch.org
>>http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev