From patchwork Tue Oct 18 15:35:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Coquelin X-Patchwork-Id: 16675 X-Patchwork-Delegate: yuanhan.liu@linux.intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 1DEAC68CF; Tue, 18 Oct 2016 17:35:55 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id CD6645A33 for ; Tue, 18 Oct 2016 17:35:50 +0200 (CEST) Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1B9FC4A54B; Tue, 18 Oct 2016 15:35:50 +0000 (UTC) Received: from max-t460s.redhat.com (vpn1-7-65.ams2.redhat.com [10.36.7.65]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u9IFZjgw019282; Tue, 18 Oct 2016 11:35:48 -0400 From: Maxime Coquelin To: yuanhan.liu@linux.intel.com, dev@dpdk.org, mst@redhat.com Cc: zhihong.wang@intel.com, ciara.loftus@intel.com, Maxime Coquelin Date: Tue, 18 Oct 2016 17:35:38 +0200 Message-Id: <1476804939-8675-2-git-send-email-maxime.coquelin@redhat.com> In-Reply-To: <1476804939-8675-1-git-send-email-maxime.coquelin@redhat.com> References: <1476804939-8675-1-git-send-email-maxime.coquelin@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 18 Oct 2016 15:35:50 +0000 (UTC) Subject: [dpdk-dev] [PATCH 1/2] vhost: Add indirect desc support to Rx mergeable path 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Windows virtio-net driver uses indirect descriptors with mergeable buffers. This patch adds its support, fixing the use of indirect descriptors with these guests. Cc: Yuanhan Liu Cc: Zhihong Wang Signed-off-by: Maxime Coquelin --- lib/librte_vhost/virtio_net.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index b784dba..0941186 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -351,29 +351,41 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id, } static inline int __attribute__((always_inline)) -fill_vec_buf(struct vhost_virtqueue *vq, uint32_t avail_idx, - uint32_t *vec_idx, struct buf_vector *buf_vec, - uint16_t *desc_chain_head, uint16_t *desc_chain_len) +fill_vec_buf(struct virtio_net *dev, struct vhost_virtqueue *vq, + uint32_t avail_idx, uint32_t *vec_idx, + struct buf_vector *buf_vec, uint16_t *desc_chain_head, + uint16_t *desc_chain_len) { uint16_t idx = vq->avail->ring[avail_idx & (vq->size - 1)]; uint32_t vec_id = *vec_idx; uint32_t len = 0; + struct vring_desc *descs = vq->desc; *desc_chain_head = idx; + + if (vq->desc[idx].flags & VRING_DESC_F_INDIRECT) { + descs = (struct vring_desc *)(uintptr_t) + gpa_to_vva(dev, vq->desc[idx].addr); + if (unlikely(!descs)) + return -1; + + idx = 0; + } + while (1) { if (unlikely(vec_id >= BUF_VECTOR_MAX || idx >= vq->size)) return -1; - len += vq->desc[idx].len; - buf_vec[vec_id].buf_addr = vq->desc[idx].addr; - buf_vec[vec_id].buf_len = vq->desc[idx].len; + len += descs[idx].len; + buf_vec[vec_id].buf_addr = descs[idx].addr; + buf_vec[vec_id].buf_len = descs[idx].len; buf_vec[vec_id].desc_idx = idx; vec_id++; - if ((vq->desc[idx].flags & VRING_DESC_F_NEXT) == 0) + if ((descs[idx].flags & VRING_DESC_F_NEXT) == 0) break; - idx = vq->desc[idx].next; + idx = descs[idx].next; } *desc_chain_len = len; @@ -386,9 +398,9 @@ fill_vec_buf(struct vhost_virtqueue *vq, uint32_t avail_idx, * Returns -1 on fail, 0 on success */ static inline int -reserve_avail_buf_mergeable(struct vhost_virtqueue *vq, uint32_t size, - struct buf_vector *buf_vec, uint16_t *num_buffers, - uint16_t avail_head) +reserve_avail_buf_mergeable(struct virtio_net *dev, struct vhost_virtqueue *vq, + uint32_t size, struct buf_vector *buf_vec, + uint16_t *num_buffers, uint16_t avail_head) { uint16_t cur_idx; uint32_t vec_idx = 0; @@ -404,8 +416,8 @@ reserve_avail_buf_mergeable(struct vhost_virtqueue *vq, uint32_t size, if (unlikely(cur_idx == avail_head)) return -1; - if (unlikely(fill_vec_buf(vq, cur_idx, &vec_idx, buf_vec, - &head_idx, &len) < 0)) + if (unlikely(fill_vec_buf(dev, vq, cur_idx, &vec_idx, buf_vec, + &head_idx, &len) < 0)) return -1; len = RTE_MIN(len, size); update_shadow_used_ring(vq, head_idx, len); @@ -546,8 +558,9 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id, for (pkt_idx = 0; pkt_idx < count; pkt_idx++) { uint32_t pkt_len = pkts[pkt_idx]->pkt_len + dev->vhost_hlen; - if (unlikely(reserve_avail_buf_mergeable(vq, pkt_len, buf_vec, - &num_buffers, avail_head) < 0)) { + if (unlikely(reserve_avail_buf_mergeable(dev, vq, + pkt_len, buf_vec, &num_buffers, + avail_head) < 0)) { LOG_DEBUG(VHOST_DATA, "(%d) failed to get enough desc from vring\n", dev->vid);