> -----Original Message----- > From: Maxime Coquelin <maxime.coque...@redhat.com> > Sent: Wednesday, January 20, 2021 5:25 AM > To: dev@dpdk.org; Xia, Chenbo <chenbo....@intel.com>; olivier.m...@6wind.com; > amore...@redhat.com; david.march...@redhat.com > Cc: Maxime Coquelin <maxime.coque...@redhat.com> > Subject: [PATCH v2 35/44] net/virtio: improve Virtio-user errors handling > > This patch adds error logs and propagates errors reported > by the backend. It also adds the device path in error logs > to make it easier to distinguish which device is facing the > issue. > > Signed-off-by: Maxime Coquelin <maxime.coque...@redhat.com> > --- > .../net/virtio/virtio_user/virtio_user_dev.c | 154 ++++++++++++------ > 1 file changed, 104 insertions(+), 50 deletions(-) > > diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c > b/drivers/net/virtio/virtio_user/virtio_user_dev.c > index 33a25f4684..95204ea955 100644 > --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c > +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c > @@ -37,10 +37,15 @@ virtio_user_create_queue(struct virtio_user_dev *dev, > uint32_t queue_sel) > * pair. > */ > struct vhost_vring_file file; > + int ret; > > file.index = queue_sel; > file.fd = dev->callfds[queue_sel]; > - dev->ops->set_vring_call(dev, &file); > + ret = dev->ops->set_vring_call(dev, &file); > + if (ret < 0) { > + PMD_INIT_LOG(ERR, "(%s) Failed to create queue %u\n", dev->path, > queue_sel); > + return -1; > + } > > return 0; > } > @@ -48,6 +53,7 @@ virtio_user_create_queue(struct virtio_user_dev *dev, > uint32_t queue_sel) > static int > virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel) > { > + int ret; > struct vhost_vring_file file; > struct vhost_vring_state state; > struct vring *vring = &dev->vrings[queue_sel]; > @@ -73,15 +79,21 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, > uint32_t queue_sel) > > state.index = queue_sel; > state.num = vring->num; > - dev->ops->set_vring_num(dev, &state); > + ret = dev->ops->set_vring_num(dev, &state); > + if (ret < 0) > + goto err; > > state.index = queue_sel; > state.num = 0; /* no reservation */ > if (dev->features & (1ULL << VIRTIO_F_RING_PACKED)) > state.num |= (1 << 15); > - dev->ops->set_vring_base(dev, &state); > + ret = dev->ops->set_vring_base(dev, &state); > + if (ret < 0) > + goto err; > > - dev->ops->set_vring_addr(dev, &addr); > + ret = dev->ops->set_vring_addr(dev, &addr); > + if (ret < 0) > + goto err; > > /* Of all per virtqueue MSGs, make sure VHOST_USER_SET_VRING_KICK comes > * lastly because vhost depends on this msg to judge if > @@ -89,9 +101,15 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, > uint32_t queue_sel) > */ > file.index = queue_sel; > file.fd = dev->kickfds[queue_sel]; > - dev->ops->set_vring_kick(dev, &file); > + ret = dev->ops->set_vring_kick(dev, &file); > + if (ret < 0) > + goto err; > > return 0; > +err: > + PMD_INIT_LOG(ERR, "(%s) Failed to kick queue %u\n", dev->path, > queue_sel); > + > + return -1; > } > > static int > @@ -103,14 +121,14 @@ virtio_user_queue_setup(struct virtio_user_dev *dev, > for (i = 0; i < dev->max_queue_pairs; ++i) { > queue_sel = 2 * i + VTNET_SQ_RQ_QUEUE_IDX; > if (fn(dev, queue_sel) < 0) { > - PMD_DRV_LOG(INFO, "setup rx vq fails: %u", i); > + PMD_DRV_LOG(ERR, "(%s) setup rx vq %u failed", > dev->path, i); > return -1; > } > } > for (i = 0; i < dev->max_queue_pairs; ++i) { > queue_sel = 2 * i + VTNET_SQ_TQ_QUEUE_IDX; > if (fn(dev, queue_sel) < 0) { > - PMD_DRV_LOG(INFO, "setup tx vq fails: %u", i); > + PMD_DRV_LOG(INFO, "(%s) setup tx vq %u failed", > dev->path, > i); > return -1; > } > } > @@ -144,7 +162,7 @@ virtio_user_dev_set_features(struct virtio_user_dev *dev) > ret = dev->ops->set_features(dev, features); > if (ret < 0) > goto error; > - PMD_DRV_LOG(INFO, "set features: %" PRIx64, features); > + PMD_DRV_LOG(INFO, "(%s) set features: 0x%" PRIx64, dev->path, features); > error: > pthread_mutex_unlock(&dev->mutex); > > @@ -172,9 +190,10 @@ virtio_user_start_device(struct virtio_user_dev *dev) > rte_mcfg_mem_read_lock(); > pthread_mutex_lock(&dev->mutex); > > + /* Vhost-user client not connected yet, will start later */ > if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER && > dev->vhostfd < 0) > - goto error; > + goto out; > > /* Step 2: share memory regions */ > ret = dev->ops->set_memory_table(dev); > @@ -182,15 +201,19 @@ virtio_user_start_device(struct virtio_user_dev *dev) > goto error; > > /* Step 3: kick queues */ > - if (virtio_user_queue_setup(dev, virtio_user_kick_queue) < 0) > + ret = virtio_user_queue_setup(dev, virtio_user_kick_queue); > + if (ret < 0) > goto error; > > /* Step 4: enable queues > * we enable the 1st queue pair by default. > */ > - dev->ops->enable_qp(dev, 0, 1); > + ret = dev->ops->enable_qp(dev, 0, 1); > + if (ret < 0) > + goto error; > > dev->started = true; > +out: > pthread_mutex_unlock(&dev->mutex); > rte_mcfg_mem_read_unlock(); > > @@ -198,6 +221,9 @@ virtio_user_start_device(struct virtio_user_dev *dev) > error: > pthread_mutex_unlock(&dev->mutex); > rte_mcfg_mem_read_unlock(); > + > + PMD_INIT_LOG(ERR, "(%s) Failed to start device\n", dev->path); > + > /* TODO: free resource here or caller to check */ > return -1; > } > @@ -206,31 +232,40 @@ int virtio_user_stop_device(struct virtio_user_dev *dev) > { > struct vhost_vring_state state; > uint32_t i; > - int error = 0; > + int ret; > > pthread_mutex_lock(&dev->mutex); > if (!dev->started) > goto out; > > - for (i = 0; i < dev->max_queue_pairs; ++i) > - dev->ops->enable_qp(dev, i, 0); > + for (i = 0; i < dev->max_queue_pairs; ++i) { > + ret = dev->ops->enable_qp(dev, i, 0); > + if (ret < 0) > + goto err; > + } > > /* Stop the backend. */ > for (i = 0; i < dev->max_queue_pairs * 2; ++i) { > state.index = i; > - if (dev->ops->get_vring_base(dev, &state) < 0) { > - PMD_DRV_LOG(ERR, "get_vring_base failed, index=%u", > - i); > - error = -1; > - goto out; > + ret = dev->ops->get_vring_base(dev, &state); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "(%s) get_vring_base failed, index=%u", > dev->path, i); > + goto err; > } > } > > dev->started = false; > + > out: > pthread_mutex_unlock(&dev->mutex); > > - return error; > + return 0; > +err: > + pthread_mutex_unlock(&dev->mutex); > + > + PMD_INIT_LOG(ERR, "(%s) Failed to stop device\n", dev->path); > + > + return -1; > } > > static inline void > @@ -270,13 +305,13 @@ virtio_user_dev_init_notify(struct virtio_user_dev *dev) > */ > callfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); > if (callfd < 0) { > - PMD_DRV_LOG(ERR, "callfd error, %s", strerror(errno)); > + PMD_DRV_LOG(ERR, "(%s) callfd error, %s", dev->path, > strerror(errno)); > break; > } > kickfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); > if (kickfd < 0) { > close(callfd); > - PMD_DRV_LOG(ERR, "kickfd error, %s", strerror(errno)); > + PMD_DRV_LOG(ERR, "(%s) kickfd error, %s", dev->path, > strerror(errno)); > break; > } > dev->callfds[i] = callfd; > @@ -304,7 +339,7 @@ virtio_user_fill_intr_handle(struct virtio_user_dev *dev) > if (!eth_dev->intr_handle) { > eth_dev->intr_handle = malloc(sizeof(*eth_dev->intr_handle)); > if (!eth_dev->intr_handle) { > - PMD_DRV_LOG(ERR, "fail to allocate intr_handle"); > + PMD_DRV_LOG(ERR, "(%s) failed to allocate intr_handle", > dev- > >path); > return -1; > } > memset(eth_dev->intr_handle, 0, sizeof(*eth_dev->intr_handle)); > @@ -335,6 +370,7 @@ virtio_user_mem_event_cb(enum rte_mem_event type > __rte_unused, > struct virtio_user_dev *dev = arg; > struct rte_memseg_list *msl; > uint16_t i; > + int ret = 0; > > /* ignore externally allocated memory */ > msl = rte_mem_virt2memseg_list(addr); > @@ -347,18 +383,29 @@ virtio_user_mem_event_cb(enum rte_mem_event type > __rte_unused, > goto exit; > > /* Step 1: pause the active queues */ > - for (i = 0; i < dev->queue_pairs; i++) > - dev->ops->enable_qp(dev, i, 0); > + for (i = 0; i < dev->queue_pairs; i++) { > + ret = dev->ops->enable_qp(dev, i, 0); > + if (ret < 0) > + goto exit; > + } > > /* Step 2: update memory regions */ > - dev->ops->set_memory_table(dev); > + ret = dev->ops->set_memory_table(dev); > + if (ret < 0) > + goto exit; > > /* Step 3: resume the active queues */ > - for (i = 0; i < dev->queue_pairs; i++) > - dev->ops->enable_qp(dev, i, 1); > + for (i = 0; i < dev->queue_pairs; i++) { > + ret = dev->ops->enable_qp(dev, i, 1); > + if (ret < 0) > + goto exit; > + } > > exit: > pthread_mutex_unlock(&dev->mutex); > + > + if (ret < 0) > + PMD_DRV_LOG(ERR, "(%s) Failed to update memory table\n", dev- > >path); > } > > static int > @@ -388,7 +435,7 @@ virtio_user_dev_setup(struct virtio_user_dev *dev) > dev->tapfds = malloc(dev->max_queue_pairs * > sizeof(int)); > if (!dev->vhostfds || !dev->tapfds) { > - PMD_INIT_LOG(ERR, "Failed to malloc"); > + PMD_INIT_LOG(ERR, "(%s) Failed to allocate > FDs", dev- > >path); > return -1; > } > > @@ -400,19 +447,25 @@ virtio_user_dev_setup(struct virtio_user_dev *dev) > VIRTIO_USER_BACKEND_VHOST_VDPA) { > dev->ops = &virtio_ops_vdpa; > } else { > - PMD_DRV_LOG(ERR, "Unknown backend type"); > + PMD_DRV_LOG(ERR, "(%s) Unknown backend type", > dev->path); > return -1; > } > } > > - if (dev->ops->setup(dev) < 0) > + if (dev->ops->setup(dev) < 0) { > + PMD_INIT_LOG(ERR, "(%s) Failed to setup backend\n", dev->path); > return -1; > + } > > - if (virtio_user_dev_init_notify(dev) < 0) > + if (virtio_user_dev_init_notify(dev) < 0) { > + PMD_INIT_LOG(ERR, "(%s) Failed to init notifiers\n", dev->path); > return -1; > + } > > - if (virtio_user_fill_intr_handle(dev) < 0) > + if (virtio_user_fill_intr_handle(dev) < 0) { > + PMD_INIT_LOG(ERR, "(%s) Failed to init interrupt handler\n", > dev- > >path); > return -1; > + } > > return 0; > } > @@ -480,7 +533,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char > *path, int queues, > } > > if (virtio_user_dev_setup(dev) < 0) { > - PMD_INIT_LOG(ERR, "backend set up fails"); > + PMD_INIT_LOG(ERR, "(%s) backend set up fails", dev->path); > return -1; > } > > @@ -490,27 +543,31 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char > *path, int queues, > > if (!dev->is_server) { > if (dev->ops->set_owner(dev) < 0) { > - PMD_INIT_LOG(ERR, "set_owner fails: %s", > - strerror(errno)); > + PMD_INIT_LOG(ERR, "(%s) Failed to set backend owner", > dev- > >path); > return -1; > } > > if (dev->ops->get_features(dev, &dev->device_features) < 0) { > - PMD_INIT_LOG(ERR, "get_features failed: %s", > - strerror(errno)); > + PMD_INIT_LOG(ERR, "(%s) Failed to get backend features", > dev->path); > return -1; > } > > > if ((dev->device_features & (1ULL << > VHOST_USER_F_PROTOCOL_FEATURES)) || > (dev->backend_type == > VIRTIO_USER_BACKEND_VHOST_VDPA)) > { > - if (dev->ops->get_protocol_features(dev, > &protocol_features)) > + if (dev->ops->get_protocol_features(dev, > &protocol_features)) > { > + PMD_INIT_LOG(ERR, "(%s) Failed to get backend > protocol > features", > + dev->path); > return -1; > + } > > dev->protocol_features &= protocol_features; > > - if (dev->ops->set_protocol_features(dev, dev- > >protocol_features)) > + if (dev->ops->set_protocol_features(dev, dev- > >protocol_features)) { > + PMD_INIT_LOG(ERR, "(%s) Failed to set backend > protocol > features", > + dev->path); > return -1; > + } > > if (!(dev->protocol_features & (1ULL << > VHOST_USER_PROTOCOL_F_MQ))) > dev->unsupported_features |= (1ull << > VIRTIO_NET_F_MQ); > @@ -577,8 +634,8 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char > *path, int queues, > if (rte_mem_event_callback_register(VIRTIO_USER_MEM_EVENT_CLB_NAME, > virtio_user_mem_event_cb, dev)) { > if (rte_errno != ENOTSUP) { > - PMD_INIT_LOG(ERR, "Failed to register mem event" > - " callback\n"); > + PMD_INIT_LOG(ERR, "(%s) Failed to register mem event > callback\n", > + dev->path); > return -1; > } > } > @@ -631,8 +688,8 @@ virtio_user_handle_mq(struct virtio_user_dev *dev, > uint16_t q_pairs) > uint8_t ret = 0; > > if (q_pairs > dev->max_queue_pairs) { > - PMD_INIT_LOG(ERR, "multi-q config %u, but only %u supported", > - q_pairs, dev->max_queue_pairs); > + PMD_INIT_LOG(ERR, "(%s) multi-q config %u, but only %u > supported", > + dev->path, q_pairs, dev->max_queue_pairs); > return -1; > } > > @@ -818,10 +875,8 @@ virtio_user_dev_set_status(struct virtio_user_dev *dev, > uint8_t status) > pthread_mutex_lock(&dev->mutex); > dev->status = status; > ret = dev->ops->set_status(dev, status); > - if (ret && ret != -ENOTSUP) { > - PMD_INIT_LOG(ERR, "Virtio-user set status failed (%d): %s", ret, > - strerror(errno)); > - } > + if (ret && ret != -ENOTSUP) > + PMD_INIT_LOG(ERR, "(%s) Failed to set backend status\n", dev- > >path); > > pthread_mutex_unlock(&dev->mutex); > return ret; > @@ -855,8 +910,7 @@ virtio_user_dev_update_status(struct virtio_user_dev *dev) > !!(dev->status & VIRTIO_CONFIG_STATUS_DEV_NEED_RESET), > !!(dev->status & VIRTIO_CONFIG_STATUS_FAILED)); > } else if (ret != -ENOTSUP) { > - PMD_INIT_LOG(ERR, "Virtio-user get status failed (%d): %s", ret, > - strerror(errno)); > + PMD_INIT_LOG(ERR, "(%s) Failed to get backend status\n", dev- > >path); > } > > pthread_mutex_unlock(&dev->mutex); > -- > 2.29.2
Reviewed-by: Chenbo Xia <chenbo....@intel.com>