[dpdk-dev,4/5] net/virtio-user: add lsc support with vhost-user adapter
Checks
Commit Message
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 and cannot be re-connected. We will force the
link state to be down.
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
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 | 35 +++++++++++++++++++++++-
4 files changed, 39 insertions(+), 2 deletions(-)
Comments
On Fri, Mar 03, 2017 at 05:56:42PM +0000, Jianfeng Tan wrote:
> 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 and cannot be re-connected. We will force the
> link state to be down.
>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> static void
> virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
> void *dst, int length)
> @@ -63,8 +77,27 @@ 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 flags;
> + int r;
> +
> + flags = fcntl(dev->vhostfd, F_GETFL);
> + fcntl(dev->vhostfd, F_SETFL, flags | O_NONBLOCK);
> + r = recv(dev->vhostfd, buf, 128, 0);
I think you need specify flag MSG_PEEK, to not consume the data if
there any?
--yliu
> + if (r == 0 || (r < 0 && errno != EAGAIN)) {
> + dev->status &= (~VIRTIO_NET_S_LINK_UP);
> + /* link can never be up again */
> + 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
> -----Original Message-----
> From: Yuanhan Liu [mailto:yuanhan.liu@linux.intel.com]
> Sent: Friday, March 17, 2017 4:29 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; david.marchand@6wind.com
> Subject: Re: [PATCH 4/5] net/virtio-user: add lsc support with vhost-user
> adapter
>
> On Fri, Mar 03, 2017 at 05:56:42PM +0000, Jianfeng Tan wrote:
> > 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 and cannot be re-connected. We will force the
> > link state to be down.
> >
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > static void
> > virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
> > void *dst, int length)
> > @@ -63,8 +77,27 @@ 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 flags;
> > + int r;
> > +
> > + flags = fcntl(dev->vhostfd, F_GETFL);
> > + fcntl(dev->vhostfd, F_SETFL, flags | O_NONBLOCK);
> > + r = recv(dev->vhostfd, buf, 128, 0);
>
> I think you need specify flag MSG_PEEK, to not consume the data if
> there any?
Thanks for catching this issue, I'll fix it in next version.
Thanks,
Jianfeng
@@ -1190,7 +1190,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)
{
@@ -112,4 +112,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_ */
@@ -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
@@ -34,10 +34,14 @@
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
#include <rte_malloc.h>
#include <rte_kvargs.h>
#include <rte_vdev.h>
+#include <rte_alarm.h>
#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,27 @@ 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 flags;
+ int r;
+
+ flags = fcntl(dev->vhostfd, F_GETFL);
+ fcntl(dev->vhostfd, F_SETFL, flags | O_NONBLOCK);
+ r = recv(dev->vhostfd, buf, 128, 0);
+ if (r == 0 || (r < 0 && errno != EAGAIN)) {
+ dev->status &= (~VIRTIO_NET_S_LINK_UP);
+ /* link can never be up again */
+ 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;