From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jianfeng Tan Subject: [PATCH v2 5/5] net/virtio-user: add lsc support Date: Tue, 28 Mar 2017 08:21:56 +0000 Message-ID: <1490689316-131625-6-git-send-email-jianfeng.tan@intel.com> References: <1488563803-87754-1-git-send-email-jianfeng.tan@intel.com> <1490689316-131625-1-git-send-email-jianfeng.tan@intel.com> Cc: yuanhan.liu@linux.intel.com, david.marchand@6wind.com, maxime.coquelin@redhat.com, Jianfeng Tan To: dev@dpdk.org Return-path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 2AED4CF80 for ; Tue, 28 Mar 2017 10:21:20 +0200 (CEST) In-Reply-To: <1490689316-131625-1-git-send-email-jianfeng.tan@intel.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" So far, virtio-user with vhost-user as the backend can only support client mode. So when vhost user backend is down, i.e., unix socket connection is broken, the connection cannot be re-connected. We will forcely set the link state to be down. Note: virtio-user with vhost-kernel as the backend still cannot support lsc now as we fail to find a way to monitor the backend, tap device, up/down events. Signed-off-by: Jianfeng Tan --- doc/guides/rel_notes/release_17_05.rst | 7 +++- drivers/net/virtio/virtio_ethdev.c | 2 +- drivers/net/virtio/virtio_ethdev.h | 2 ++ drivers/net/virtio/virtio_user/virtio_user_dev.c | 2 ++ drivers/net/virtio/virtio_user_ethdev.c | 45 +++++++++++++++++++++++- 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst index 2b5eaab..42ba190 100644 --- a/doc/guides/rel_notes/release_17_05.rst +++ b/doc/guides/rel_notes/release_17_05.rst @@ -59,11 +59,12 @@ New Features * **Added interrupt mode support for virtio-user.** - Implemented Rxq interrupt mode support for virtio-user as a virtual + Implemented Rxq interrupt mode and LSC support for virtio-user as a virtual device. Supported cases: * Rxq interrupt for virtio-user + vhost-user as the backend. * Rxq interrupt for virtio-user + vhost-kernel as the backend. + * LSC interrupt for virtio-user + vhost-user as the backend. Resolved Issues --------------- @@ -119,6 +120,10 @@ Known Issues Also, make sure to start the actual text at the margin. ========================================================= + * **LSC interrupt cannot work for virtio-user + vhost-kernel.** + + LSC interrupt cannot be detected when setting the backend, tap device, + up/down as we fail to find a way to monitor such event. API Changes ----------- diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index f0213ba..952cf70 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -1205,7 +1205,7 @@ virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features) * Process Virtio Config changed interrupt and call the callback * if link state changed. */ -static void +void virtio_interrupt_handler(struct rte_intr_handle *handle, void *param) { diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h index aa78adc..4009c4d 100644 --- a/drivers/net/virtio/virtio_ethdev.h +++ b/drivers/net/virtio/virtio_ethdev.h @@ -113,4 +113,6 @@ uint16_t virtio_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, int eth_virtio_dev_init(struct rte_eth_dev *eth_dev); +void virtio_interrupt_handler(struct rte_intr_handle *handle, void *param); + #endif /* _VIRTIO_ETHDEV_H_ */ diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c index 5637ccf..d19623d 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c @@ -158,6 +158,8 @@ virtio_user_fill_intr_handle(struct virtio_user_dev *dev, uint8_t portid) eth_dev->intr_handle->nb_efd = dev->max_queue_pairs; eth_dev->intr_handle->max_intr = dev->max_queue_pairs + 1; eth_dev->intr_handle->type = RTE_INTR_HANDLE_VDEV; + if (dev->vhostfd >= 0) + eth_dev->intr_handle->fd = dev->vhostfd; } int diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c index 5190029..2c698c8 100644 --- a/drivers/net/virtio/virtio_user_ethdev.c +++ b/drivers/net/virtio/virtio_user_ethdev.c @@ -34,10 +34,14 @@ #include #include #include +#include +#include +#include #include #include #include +#include #include "virtio_ethdev.h" #include "virtio_logs.h" @@ -49,6 +53,16 @@ #define virtio_user_get_dev(hw) \ ((struct virtio_user_dev *)(hw)->virtio_user_dev) +static void virtio_user_delayed_handler(void *param) +{ + struct virtio_hw *hw = (struct virtio_hw *)param; + struct rte_eth_dev *dev = &rte_eth_devices[hw->port_id]; + + rte_intr_callback_unregister(dev->intr_handle, + virtio_interrupt_handler, + dev); +} + static void virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset, void *dst, int length) @@ -63,8 +77,37 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset, return; } - if (offset == offsetof(struct virtio_net_config, status)) + if (offset == offsetof(struct virtio_net_config, status)) { + char buf[128]; + + if (dev->vhostfd >= 0) { + int r; + int flags; + + flags = fcntl(dev->vhostfd, F_GETFL); + fcntl(dev->vhostfd, F_SETFL, flags | O_NONBLOCK); + r = recv(dev->vhostfd, buf, 128, MSG_PEEK); + if (r == 0 || (r < 0 && errno != EAGAIN)) { + dev->status &= (~VIRTIO_NET_S_LINK_UP); + PMD_DRV_LOG(ERR, "virtio-user port %u is down", + hw->port_id); + /* Only client mode is available now. Once the + * connection is broken, it can never be up + * again. Besides, this function could be called + * in the process of interrupt handling, + * callback cannot be unregistered here, set an + * alarm to do it. + */ + rte_eal_alarm_set(1, + virtio_user_delayed_handler, + (void *)hw); + } else { + dev->status |= VIRTIO_NET_S_LINK_UP; + } + fcntl(dev->vhostfd, F_SETFL, flags & (~O_NONBLOCK)); + } *(uint16_t *)dst = dev->status; + } if (offset == offsetof(struct virtio_net_config, max_virtqueue_pairs)) *(uint16_t *)dst = dev->max_queue_pairs; -- 2.7.4