rte_vhost: fix deadlock on rte_vhost_driver_unregister()
when qemu connect to vhost, but don't send msg to vhost. We use kill -15 to destroy vhost process. it will lead to deadlock. (A) * rte_vhost_driver_unregister() * pthread_mutex_lock hold vhost_user.mutex (1) * wait TAILQ_FIRST(&vsocket->conn_list) is NULL (B) * fdset_event_dispatch() * vhost_user_read_cb() start * vhost_user_msg_handler() start * dev->notify_ops is NULL because qemu just connect, no message recv. * vhost_driver_callback_get() * pthread_mutex_lock hold vhost_user.mutex (2) (A) & (B) deadlock To avoid this scenes, when qemu connect in vhost_new_device() initialize dev->notify_ops Change-Id: Iaf699da41dfa3088cfc0f09688b50fada6b2c8d6 Signed-off-by: Tianyu yang <yangtianyu2@huawei.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/454832 Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
4003ebf73c
commit
151a357ca3
@ -220,7 +220,7 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
|
||||
return;
|
||||
}
|
||||
|
||||
vid = vhost_new_device(vsocket->features);
|
||||
vid = vhost_new_device(vsocket->features, vsocket->notify_ops);
|
||||
if (vid == -1) {
|
||||
goto err;
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ reset_device(struct virtio_net *dev)
|
||||
* there is a new virtio device being attached).
|
||||
*/
|
||||
int
|
||||
vhost_new_device(uint64_t features)
|
||||
vhost_new_device(uint64_t features, struct vhost_device_ops const *ops)
|
||||
{
|
||||
struct virtio_net *dev;
|
||||
int i;
|
||||
@ -207,6 +207,7 @@ vhost_new_device(uint64_t features)
|
||||
vhost_devices[i] = dev;
|
||||
dev->vid = i;
|
||||
dev->features = features;
|
||||
dev->notify_ops = ops;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ gpa_to_hpa(struct virtio_net *dev, uint64_t gpa, uint64_t size)
|
||||
|
||||
struct virtio_net *get_device(int vid);
|
||||
|
||||
int vhost_new_device(uint64_t features);
|
||||
int vhost_new_device(uint64_t features, struct vhost_device_ops const *ops);
|
||||
void cleanup_device(struct virtio_net *dev, int destroy);
|
||||
void reset_device(struct virtio_net *dev);
|
||||
void vhost_destroy_device(int);
|
||||
|
@ -1217,16 +1217,6 @@ vhost_user_msg_handler(int vid, int fd)
|
||||
if (dev == NULL)
|
||||
return -1;
|
||||
|
||||
if (!dev->notify_ops) {
|
||||
dev->notify_ops = vhost_driver_callback_get(dev->ifname);
|
||||
if (!dev->notify_ops) {
|
||||
RTE_LOG(ERR, VHOST_CONFIG,
|
||||
"failed to get callback ops for driver %s\n",
|
||||
dev->ifname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = read_vhost_message(fd, &msg);
|
||||
if (ret <= 0 || msg.request >= VHOST_USER_MAX) {
|
||||
if (ret < 0)
|
||||
|
Loading…
Reference in New Issue
Block a user