From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id B6D8A1C4A for ; Fri, 5 May 2017 15:57:25 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0E4D761BA9; Fri, 5 May 2017 13:57:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 0E4D761BA9 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jfreiman@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 0E4D761BA9 Received: from virtlab417.ml3.eng.bos.redhat.com (virtlab417.ml3.eng.bos.redhat.com [10.19.176.175]) by smtp.corp.redhat.com (Postfix) with ESMTP id BB56381B6A; Fri, 5 May 2017 13:57:24 +0000 (UTC) From: Jens Freimann To: yuanhan.liu@linux.intel.com Cc: dev@dpdk.org Date: Fri, 5 May 2017 09:57:13 -0400 Message-Id: <1493992642-52756-3-git-send-email-jfreiman@redhat.com> In-Reply-To: <1493992642-52756-1-git-send-email-jfreiman@redhat.com> References: <1493992642-52756-1-git-send-email-jfreiman@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 05 May 2017 13:57:25 +0000 (UTC) Subject: [dpdk-dev] [RFC PATCH 02/11] net/virtio: implement 1.1 guest Tx X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 May 2017 13:57:26 -0000 From: Yuanhan Liu build only so far Signed-off-by: Yuanhan Liu --- drivers/net/virtio/Makefile | 1 + drivers/net/virtio/virtio_ethdev.c | 24 ++++-- drivers/net/virtio/virtio_ethdev.h | 3 + drivers/net/virtio/virtio_rxtx.c | 3 + drivers/net/virtio/virtio_rxtx_1.1.c | 159 +++++++++++++++++++++++++++++++++++ 5 files changed, 183 insertions(+), 7 deletions(-) create mode 100644 drivers/net/virtio/virtio_rxtx_1.1.c diff --git a/drivers/net/virtio/Makefile b/drivers/net/virtio/Makefile index b21b878..4c4ff42 100644 --- a/drivers/net/virtio/Makefile +++ b/drivers/net/virtio/Makefile @@ -49,6 +49,7 @@ LIBABIVER := 1 SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtqueue.c SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_pci.c SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_rxtx.c +SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_rxtx_1.1.c SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_ethdev.c SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_rxtx_simple.c diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index a5db503..553c27a 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -334,12 +334,12 @@ struct rte_virtio_xstats_name_off { vq->vq_desc_tail_idx = (uint16_t)(vq->vq_nentries - 1); vring_desc_init(vr->desc, size); - } - /* - * Disable device(host) interrupting guest - */ - virtqueue_disable_intr(vq); + /* + * Disable device(host) interrupting guest + */ + virtqueue_disable_intr(vq); + } } static int @@ -625,7 +625,8 @@ struct rte_virtio_xstats_name_off { } vtpci_reset(hw); - virtio_dev_free_mbufs(dev); + if (!vtpci_version_1_1(hw)) + virtio_dev_free_mbufs(dev); virtio_free_queues(hw); } @@ -1534,7 +1535,6 @@ static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev, RTE_BUILD_BUG_ON(RTE_PKTMBUF_HEADROOM < sizeof(struct virtio_net_hdr_mrg_rxbuf)); eth_dev->dev_ops = &virtio_eth_dev_ops; - eth_dev->tx_pkt_burst = &virtio_xmit_pkts; if (rte_eal_process_type() == RTE_PROC_SECONDARY) { if (!hw->virtio_user_dev) { @@ -1578,6 +1578,12 @@ static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev, if (ret < 0) return ret; + /* FIXME: as second process? */ + if (vtpci_version_1_1(hw)) + eth_dev->tx_pkt_burst = &virtio_xmit_pkts_1_1; + else + eth_dev->tx_pkt_burst = &virtio_xmit_pkts; + /* Setup interrupt callback */ if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) rte_intr_callback_register(eth_dev->intr_handle, @@ -1749,6 +1755,10 @@ static int eth_virtio_pci_remove(struct rte_pci_device *pci_dev) } } + /*no rx support for virtio 1.1 yet*/ + if (vtpci_version_1_1(hw)) + return 0; + /*Notify the backend *Otherwise the tap backend might already stop its queue due to fullness. *vhost backend will have no chance to be waked up diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h index c3413c6..deed34e 100644 --- a/drivers/net/virtio/virtio_ethdev.h +++ b/drivers/net/virtio/virtio_ethdev.h @@ -69,6 +69,7 @@ 1u << VIRTIO_NET_F_MTU | \ 1u << VIRTIO_RING_F_INDIRECT_DESC | \ 1ULL << VIRTIO_F_VERSION_1 | \ + 1ULL << VIRTIO_F_VERSION_1_1 | \ 1ULL << VIRTIO_F_IOMMU_PLATFORM) #define VIRTIO_PMD_SUPPORTED_GUEST_FEATURES \ @@ -104,6 +105,8 @@ uint16_t virtio_recv_mergeable_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts); +uint16_t virtio_xmit_pkts_1_1(void *tx_queue, struct rte_mbuf **tx_pkts, + uint16_t nb_pkts); uint16_t virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c index fbc96df..e697192 100644 --- a/drivers/net/virtio/virtio_rxtx.c +++ b/drivers/net/virtio/virtio_rxtx.c @@ -427,6 +427,9 @@ PMD_INIT_FUNC_TRACE(); + if (vtpci_version_1_1(hw)) + return 0; + if (nb_desc == 0 || nb_desc > vq->vq_nentries) nb_desc = vq->vq_nentries; vq->vq_free_cnt = RTE_MIN(vq->vq_free_cnt, nb_desc); diff --git a/drivers/net/virtio/virtio_rxtx_1.1.c b/drivers/net/virtio/virtio_rxtx_1.1.c new file mode 100644 index 0000000..e47a346 --- /dev/null +++ b/drivers/net/virtio/virtio_rxtx_1.1.c @@ -0,0 +1,159 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "virtio_logs.h" +#include "virtio_ethdev.h" +#include "virtio_pci.h" +#include "virtqueue.h" +#include "virtio_rxtx.h" + +/* Cleanup from completed transmits. */ +static void +virtio_xmit_cleanup(struct virtqueue *vq) +{ + uint16_t idx; + uint16_t size = vq->vq_nentries; + struct vring_desc_1_1 *desc = vq->vq_ring.desc_1_1; + + idx = vq->vq_used_cons_idx & (size - 1); + while ((desc[idx].flags & DESC_HW) == 0) { + struct vq_desc_extra *dxp; + + dxp = &vq->vq_descx[idx]; + if (dxp->cookie != NULL) { + rte_pktmbuf_free(dxp->cookie); + dxp->cookie = NULL; + } + + idx = (++vq->vq_used_cons_idx) & (size - 1); + vq->vq_free_cnt++; + + if (vq->vq_free_cnt >= size) + break; + } +} + +static inline void +virtio_xmit(struct virtnet_tx *txvq, struct rte_mbuf *mbuf) +{ + struct virtio_tx_region *txr = txvq->virtio_net_hdr_mz->addr; + struct virtqueue *vq = txvq->vq; + struct vring_desc_1_1 *desc = vq->vq_ring.desc_1_1; + uint16_t idx; + uint16_t head_idx = (vq->vq_avail_idx++) & (vq->vq_nentries - 1); + + idx = head_idx; + vq->vq_free_cnt -= mbuf->nb_segs + 1; + vq->vq_descx[idx].cookie = mbuf; + + desc[idx].addr = txvq->virtio_net_hdr_mem + + RTE_PTR_DIFF(&txr[idx].tx_hdr, txr); + desc[idx].len = vq->hw->vtnet_hdr_size; + desc[idx].flags = VRING_DESC_F_NEXT; + + do { + idx = (vq->vq_avail_idx++) & (vq->vq_nentries - 1); + desc[idx].addr = VIRTIO_MBUF_DATA_DMA_ADDR(mbuf, vq); + desc[idx].len = mbuf->data_len; + desc[idx].flags = DESC_HW | VRING_DESC_F_NEXT; + } while ((mbuf = mbuf->next) != NULL); + + desc[idx].flags &= ~VRING_DESC_F_NEXT; + + /* + * update the head last, so that when the host saw such flag + * is set, it means all others in the same chain is also set + */ + rte_smp_wmb(); + desc[head_idx].flags |= DESC_HW; +} + +uint16_t +virtio_xmit_pkts_1_1(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +{ + struct virtnet_tx *txvq = tx_queue; + struct virtqueue *vq = txvq->vq; + uint16_t i; + + if (unlikely(nb_pkts < 1)) + return nb_pkts; + + PMD_TX_LOG(DEBUG, "%d packets to xmit", nb_pkts); + + for (i = 0; i < nb_pkts; i++) { + struct rte_mbuf *txm = tx_pkts[i]; + + if (unlikely(txm->nb_segs + 1 > vq->vq_free_cnt)) { + virtio_xmit_cleanup(vq); + + if (unlikely(txm->nb_segs + 1 > vq->vq_free_cnt)) { + PMD_TX_LOG(ERR, + "No free tx descriptors to transmit"); + break; + } + } + + virtio_xmit(txvq, txm); + txvq->stats.bytes += txm->pkt_len; + } + + txvq->stats.packets += i; + txvq->stats.errors += nb_pkts - i; + + return i; +} -- 1.8.3.1