From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 98A5195DB for ; Thu, 22 Oct 2015 14:35:58 +0200 (CEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 22 Oct 2015 05:35:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,182,1444719600"; d="scan'208";a="832542862" Received: from yliu-dev.sh.intel.com ([10.239.66.49]) by orsmga002.jf.intel.com with ESMTP; 22 Oct 2015 05:35:35 -0700 From: Yuanhan Liu To: dev@dpdk.org Date: Thu, 22 Oct 2015 20:35:54 +0800 Message-Id: <1445517356-19780-7-git-send-email-yuanhan.liu@linux.intel.com> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1445517356-19780-1-git-send-email-yuanhan.liu@linux.intel.com> References: <1445399294-18826-1-git-send-email-yuanhan.liu@linux.intel.com> <1445517356-19780-1-git-send-email-yuanhan.liu@linux.intel.com> Cc: "Michael S. Tsirkin" , marcel@redhat.com, Changchun Ouyang Subject: [dpdk-dev] [PATCH v8 6/8] vhost: add VHOST_USER_SET_VRING_ENABLE message X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Oct 2015 12:35:59 -0000 From: Changchun Ouyang This message is used to enable/disable a specific vring queue pair. The first queue pair is enabled by default. Signed-off-by: Changchun Ouyang Signed-off-by: Yuanhan Liu Acked-by: Flavio Leitner --- v7: invoke vring_state_changed() callback once for each queue pair. v6: add a vring state changed callback, for informing the application that a specific vring is enabled/disabled. You could either flush packets haven't been processed yet, or simply just drop them. --- lib/librte_vhost/rte_virtio_net.h | 9 ++++++++- lib/librte_vhost/vhost_rxtx.c | 10 ++++++++++ lib/librte_vhost/vhost_user/vhost-net-user.c | 5 +++++ lib/librte_vhost/vhost_user/vhost-net-user.h | 1 + lib/librte_vhost/vhost_user/virtio-net-user.c | 27 +++++++++++++++++++++++++++ lib/librte_vhost/vhost_user/virtio-net-user.h | 3 +++ lib/librte_vhost/virtio-net.c | 12 +++++++++--- 7 files changed, 63 insertions(+), 4 deletions(-) diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h index 9a32a95..426a70d 100644 --- a/lib/librte_vhost/rte_virtio_net.h +++ b/lib/librte_vhost/rte_virtio_net.h @@ -89,6 +89,7 @@ struct vhost_virtqueue { volatile uint16_t last_used_idx_res; /**< Used for multiple devices reserving buffers. */ int callfd; /**< Used to notify the guest (trigger interrupt). */ int kickfd; /**< Currently unused as polling mode is enabled. */ + int enabled; struct buf_vector buf_vec[BUF_VECTOR_MAX]; /**< for scatter RX. */ } __rte_cache_aligned; @@ -132,7 +133,7 @@ struct virtio_memory { }; /** - * Device operations to add/remove device. + * Device and vring operations. * * Make sure to set VIRTIO_DEV_RUNNING to the device flags in new_device and * remove it in destroy_device. @@ -141,12 +142,18 @@ struct virtio_memory { struct virtio_net_device_ops { int (*new_device)(struct virtio_net *); /**< Add device. */ void (*destroy_device)(volatile struct virtio_net *); /**< Remove device. */ + + int (*vring_state_changed)(struct virtio_net *dev, uint16_t queue_id, int enable); /**< triggered when a vring is enabled or disabled */ }; static inline uint16_t __attribute__((always_inline)) rte_vring_available_entries(struct virtio_net *dev, uint16_t queue_id) { struct vhost_virtqueue *vq = dev->virtqueue[queue_id]; + + if (!vq->enabled) + return 0; + return *(volatile uint16_t *)&vq->avail->idx - vq->last_used_idx_res; } diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c index 1ec8850..9322ce6 100644 --- a/lib/librte_vhost/vhost_rxtx.c +++ b/lib/librte_vhost/vhost_rxtx.c @@ -83,6 +83,9 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id, } vq = dev->virtqueue[queue_id]; + if (unlikely(vq->enabled == 0)) + return 0; + count = (count > MAX_PKT_BURST) ? MAX_PKT_BURST : count; /* @@ -275,6 +278,7 @@ copy_from_mbuf_to_vring(struct virtio_net *dev, uint32_t queue_id, * (guest physical addr -> vhost virtual addr) */ vq = dev->virtqueue[queue_id]; + vb_addr = gpa_to_vva(dev, vq->buf_vec[vec_idx].buf_addr); vb_hdr_addr = vb_addr; @@ -482,6 +486,9 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id, } vq = dev->virtqueue[queue_id]; + if (unlikely(vq->enabled == 0)) + return 0; + count = RTE_MIN((uint32_t)MAX_PKT_BURST, count); if (count == 0) @@ -583,6 +590,9 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id, } vq = dev->virtqueue[queue_id]; + if (unlikely(vq->enabled == 0)) + return 0; + avail_idx = *((volatile uint16_t *)&vq->avail->idx); /* If there are no available buffers then return. */ diff --git a/lib/librte_vhost/vhost_user/vhost-net-user.c b/lib/librte_vhost/vhost_user/vhost-net-user.c index 8675cd4..f681676 100644 --- a/lib/librte_vhost/vhost_user/vhost-net-user.c +++ b/lib/librte_vhost/vhost_user/vhost-net-user.c @@ -99,6 +99,7 @@ static const char *vhost_message_str[VHOST_USER_MAX] = { [VHOST_USER_GET_PROTOCOL_FEATURES] = "VHOST_USER_GET_PROTOCOL_FEATURES", [VHOST_USER_SET_PROTOCOL_FEATURES] = "VHOST_USER_SET_PROTOCOL_FEATURES", [VHOST_USER_GET_QUEUE_NUM] = "VHOST_USER_GET_QUEUE_NUM", + [VHOST_USER_SET_VRING_ENABLE] = "VHOST_USER_SET_VRING_ENABLE", }; /** @@ -428,6 +429,10 @@ vserver_message_handler(int connfd, void *dat, int *remove) send_vhost_message(connfd, &msg); break; + case VHOST_USER_SET_VRING_ENABLE: + user_set_vring_enable(ctx, &msg.payload.state); + break; + default: break; diff --git a/lib/librte_vhost/vhost_user/vhost-net-user.h b/lib/librte_vhost/vhost_user/vhost-net-user.h index 389d21d..38637cc 100644 --- a/lib/librte_vhost/vhost_user/vhost-net-user.h +++ b/lib/librte_vhost/vhost_user/vhost-net-user.h @@ -66,6 +66,7 @@ typedef enum VhostUserRequest { VHOST_USER_GET_PROTOCOL_FEATURES = 15, VHOST_USER_SET_PROTOCOL_FEATURES = 16, VHOST_USER_GET_QUEUE_NUM = 17, + VHOST_USER_SET_VRING_ENABLE = 18, VHOST_USER_MAX } VhostUserRequest; diff --git a/lib/librte_vhost/vhost_user/virtio-net-user.c b/lib/librte_vhost/vhost_user/virtio-net-user.c index d62f3d7..6ebbd4f 100644 --- a/lib/librte_vhost/vhost_user/virtio-net-user.c +++ b/lib/librte_vhost/vhost_user/virtio-net-user.c @@ -312,6 +312,33 @@ user_get_vring_base(struct vhost_device_ctx ctx, return 0; } +/* + * when virtio queues are ready to work, qemu will send us to + * enable the virtio queue pair. + */ +int +user_set_vring_enable(struct vhost_device_ctx ctx, + struct vhost_vring_state *state) +{ + struct virtio_net *dev = get_device(ctx); + uint16_t base_idx = state->index; + int enable = (int)state->num; + + RTE_LOG(INFO, VHOST_CONFIG, + "set queue enable: %d to qp idx: %d\n", + enable, state->index); + + if (notify_ops->vring_state_changed) { + notify_ops->vring_state_changed(dev, base_idx / VIRTIO_QNUM, + enable); + } + + dev->virtqueue[base_idx + VIRTIO_RXQ]->enabled = enable; + dev->virtqueue[base_idx + VIRTIO_TXQ]->enabled = enable; + + return 0; +} + void user_destroy_device(struct vhost_device_ctx ctx) { diff --git a/lib/librte_vhost/vhost_user/virtio-net-user.h b/lib/librte_vhost/vhost_user/virtio-net-user.h index e7a6ff4..d46057e 100644 --- a/lib/librte_vhost/vhost_user/virtio-net-user.h +++ b/lib/librte_vhost/vhost_user/virtio-net-user.h @@ -50,5 +50,8 @@ void user_set_protocol_features(struct vhost_device_ctx ctx, int user_get_vring_base(struct vhost_device_ctx, struct vhost_vring_state *); +int user_set_vring_enable(struct vhost_device_ctx ctx, + struct vhost_vring_state *state); + void user_destroy_device(struct vhost_device_ctx); #endif diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c index 772f835..48629d0 100644 --- a/lib/librte_vhost/virtio-net.c +++ b/lib/librte_vhost/virtio-net.c @@ -254,7 +254,7 @@ rm_config_ll_entry(struct virtio_net_config_ll *ll_dev, } static void -init_vring_queue(struct vhost_virtqueue *vq) +init_vring_queue(struct vhost_virtqueue *vq, int qp_idx) { memset(vq, 0, sizeof(struct vhost_virtqueue)); @@ -263,13 +263,19 @@ init_vring_queue(struct vhost_virtqueue *vq) /* Backends are set to -1 indicating an inactive device. */ vq->backend = -1; + + /* always set the default vq pair to enabled */ + if (qp_idx == 0) + vq->enabled = 1; } static void init_vring_queue_pair(struct virtio_net *dev, uint32_t qp_idx) { - init_vring_queue(dev->virtqueue[qp_idx * VIRTIO_QNUM + VIRTIO_RXQ]); - init_vring_queue(dev->virtqueue[qp_idx * VIRTIO_QNUM + VIRTIO_TXQ]); + uint32_t base_idx = qp_idx * VIRTIO_QNUM; + + init_vring_queue(dev->virtqueue[base_idx + VIRTIO_RXQ], qp_idx); + init_vring_queue(dev->virtqueue[base_idx + VIRTIO_TXQ], qp_idx); } static int -- 1.9.0