Message ID | 20220617024229.706826-1-yuanx.wang@intel.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Maxime Coquelin |
Headers | show |
Series | net/virtio: fix socket nonblocking mode affects initialization | expand |
Context | Check | Description |
---|---|---|
ci/iol-abi-testing | success | Testing PASS |
ci/intel-Testing | success | Testing PASS |
ci/github-robot: build | success | github build: passed |
ci/iol-x86_64-compile-testing | success | Testing PASS |
ci/iol-x86_64-unit-testing | success | Testing PASS |
ci/iol-intel-Functional | success | Functional Testing PASS |
ci/iol-intel-Performance | success | Performance Testing PASS |
ci/iol-aarch64-compile-testing | success | Testing PASS |
ci/iol-aarch64-unit-testing | success | Testing PASS |
ci/Intel-compilation | success | Compilation OK |
ci/iol-mellanox-Performance | success | Performance Testing PASS |
ci/checkpatch | success | coding style OK |
On Fri, 17 Jun 2022 10:42:29 +0800 Yuan Wang <yuanx.wang@intel.com> wrote: > The virtio-user initialization requires unix socket to receive backend > messages in block mode. However, vhost_user_update_link_state() sets > the same socket to nonblocking via fcntl, which affects all threads. > Enabling the rxq interrupt can causes both of these behaviors to occur > concurrently, with the result that the initialization may fail > because no messages are received in nonblocking socket. > > Thread 1: > virtio_init_device() > --> virtio_user_start_device() > --> vhost_user_set_memory_table() > --> vhost_user_check_reply_ack() > > Thread 2: > virtio_interrupt_handler() > --> vhost_user_update_link_state() > > Fix that by replacing O_NONBLOCK with the recv per-call option > MSG_DONTWAIT. > > Fixes: ef53b6030039 ("net/virtio-user: support LSC") > Cc: stable@dpdk.org > > Signed-off-by: Yuan Wang <yuanx.wang@intel.com> Looks good and saves a few system calls. Acked-by: Stephen Hemminger <stephen@networkplumber.org>
> -----Original Message----- > From: Wang, YuanX <yuanx.wang@intel.com> > Sent: Friday, June 17, 2022 10:42 AM > To: maxime.coquelin@redhat.com; Xia, Chenbo <chenbo.xia@intel.com>; > dev@dpdk.org > Cc: Hu, Jiayu <jiayu.hu@intel.com>; He, Xingguang <xingguang.he@intel.com>; > Wang, YuanX <yuanx.wang@intel.com>; stable@dpdk.org > Subject: [PATCH] net/virtio: fix socket nonblocking mode affects > initialization > > The virtio-user initialization requires unix socket to receive backend > messages in block mode. However, vhost_user_update_link_state() sets > the same socket to nonblocking via fcntl, which affects all threads. > Enabling the rxq interrupt can causes both of these behaviors to occur > concurrently, with the result that the initialization may fail > because no messages are received in nonblocking socket. > > Thread 1: > virtio_init_device() > --> virtio_user_start_device() > --> vhost_user_set_memory_table() > --> vhost_user_check_reply_ack() > > Thread 2: > virtio_interrupt_handler() > --> vhost_user_update_link_state() > > Fix that by replacing O_NONBLOCK with the recv per-call option > MSG_DONTWAIT. > > Fixes: ef53b6030039 ("net/virtio-user: support LSC") > Cc: stable@dpdk.org > > Signed-off-by: Yuan Wang <yuanx.wang@intel.com> > --- > drivers/net/virtio/virtio_user/vhost_user.c | 15 +-------------- > 1 file changed, 1 insertion(+), 14 deletions(-) > > diff --git a/drivers/net/virtio/virtio_user/vhost_user.c > b/drivers/net/virtio/virtio_user/vhost_user.c > index 7d1749114d..198bd63d3c 100644 > --- a/drivers/net/virtio/virtio_user/vhost_user.c > +++ b/drivers/net/virtio/virtio_user/vhost_user.c > @@ -940,15 +940,8 @@ vhost_user_update_link_state(struct virtio_user_dev > *dev) > > if (data->vhostfd >= 0) { > int r; > - int flags; > > - flags = fcntl(data->vhostfd, F_GETFL); > - if (fcntl(data->vhostfd, F_SETFL, flags | O_NONBLOCK) == -1) { > - PMD_DRV_LOG(ERR, "error setting O_NONBLOCK flag"); > - return -1; > - } > - > - r = recv(data->vhostfd, buf, 128, MSG_PEEK); > + r = recv(data->vhostfd, buf, 128, MSG_PEEK | MSG_DONTWAIT); > if (r == 0 || (r < 0 && errno != EAGAIN)) { > dev->net_status &= (~VIRTIO_NET_S_LINK_UP); > PMD_DRV_LOG(ERR, "virtio-user port %u is down", dev- > >hw.port_id); > @@ -963,12 +956,6 @@ vhost_user_update_link_state(struct virtio_user_dev > *dev) > } else { > dev->net_status |= VIRTIO_NET_S_LINK_UP; > } > - > - if (fcntl(data->vhostfd, F_SETFL, > - flags & ~O_NONBLOCK) == -1) { > - PMD_DRV_LOG(ERR, "error clearing O_NONBLOCK flag"); > - return -1; > - } > } else if (dev->is_server) { > dev->net_status &= (~VIRTIO_NET_S_LINK_UP); > if (virtio_user_dev_server_reconnect(dev) >= 0) > -- > 2.25.1 Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
On 6/17/22 04:42, Yuan Wang wrote: > The virtio-user initialization requires unix socket to receive backend > messages in block mode. However, vhost_user_update_link_state() sets > the same socket to nonblocking via fcntl, which affects all threads. > Enabling the rxq interrupt can causes both of these behaviors to occur > concurrently, with the result that the initialization may fail > because no messages are received in nonblocking socket. > > Thread 1: > virtio_init_device() > --> virtio_user_start_device() > --> vhost_user_set_memory_table() > --> vhost_user_check_reply_ack() > > Thread 2: > virtio_interrupt_handler() > --> vhost_user_update_link_state() > > Fix that by replacing O_NONBLOCK with the recv per-call option > MSG_DONTWAIT. > > Fixes: ef53b6030039 ("net/virtio-user: support LSC") > Cc: stable@dpdk.org > > Signed-off-by: Yuan Wang <yuanx.wang@intel.com> > --- > drivers/net/virtio/virtio_user/vhost_user.c | 15 +-------------- > 1 file changed, 1 insertion(+), 14 deletions(-) > Applied to dpdk-next-virtio/main. Thanks, Maxime
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c index 7d1749114d..198bd63d3c 100644 --- a/drivers/net/virtio/virtio_user/vhost_user.c +++ b/drivers/net/virtio/virtio_user/vhost_user.c @@ -940,15 +940,8 @@ vhost_user_update_link_state(struct virtio_user_dev *dev) if (data->vhostfd >= 0) { int r; - int flags; - flags = fcntl(data->vhostfd, F_GETFL); - if (fcntl(data->vhostfd, F_SETFL, flags | O_NONBLOCK) == -1) { - PMD_DRV_LOG(ERR, "error setting O_NONBLOCK flag"); - return -1; - } - - r = recv(data->vhostfd, buf, 128, MSG_PEEK); + r = recv(data->vhostfd, buf, 128, MSG_PEEK | MSG_DONTWAIT); if (r == 0 || (r < 0 && errno != EAGAIN)) { dev->net_status &= (~VIRTIO_NET_S_LINK_UP); PMD_DRV_LOG(ERR, "virtio-user port %u is down", dev->hw.port_id); @@ -963,12 +956,6 @@ vhost_user_update_link_state(struct virtio_user_dev *dev) } else { dev->net_status |= VIRTIO_NET_S_LINK_UP; } - - if (fcntl(data->vhostfd, F_SETFL, - flags & ~O_NONBLOCK) == -1) { - PMD_DRV_LOG(ERR, "error clearing O_NONBLOCK flag"); - return -1; - } } else if (dev->is_server) { dev->net_status &= (~VIRTIO_NET_S_LINK_UP); if (virtio_user_dev_server_reconnect(dev) >= 0)
The virtio-user initialization requires unix socket to receive backend messages in block mode. However, vhost_user_update_link_state() sets the same socket to nonblocking via fcntl, which affects all threads. Enabling the rxq interrupt can causes both of these behaviors to occur concurrently, with the result that the initialization may fail because no messages are received in nonblocking socket. Thread 1: virtio_init_device() --> virtio_user_start_device() --> vhost_user_set_memory_table() --> vhost_user_check_reply_ack() Thread 2: virtio_interrupt_handler() --> vhost_user_update_link_state() Fix that by replacing O_NONBLOCK with the recv per-call option MSG_DONTWAIT. Fixes: ef53b6030039 ("net/virtio-user: support LSC") Cc: stable@dpdk.org Signed-off-by: Yuan Wang <yuanx.wang@intel.com> --- drivers/net/virtio/virtio_user/vhost_user.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-)