From: Huawei Xie Date: Thu, 29 Oct 2015 14:53:22 +0000 (+0800) Subject: virtio: fill Rx avail ring with blank mbufs X-Git-Tag: spdx-start~8196 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=cab0461234e7650c521bbfbb9748a730def053be;p=dpdk.git virtio: fill Rx avail ring with blank mbufs Add software RX ring in virtqueue. Add fake_mbuf in virtqueue for wraparound processing. Fill avail ring with blank mbufs in virtio_dev_vring_start Add virtio_rxtx.h header file for RTE_VIRTIO_PMD_MAX_BURST. Would move all rx/tx related declarations into this header file in future. Signed-off-by: Huawei Xie Acked-by: Jianfeng Tan --- diff --git a/drivers/net/virtio/Makefile b/drivers/net/virtio/Makefile index 930b60f28c..43835bab52 100644 --- a/drivers/net/virtio/Makefile +++ b/drivers/net/virtio/Makefile @@ -50,7 +50,7 @@ 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_ethdev.c - +SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_rxtx_simple.c # this lib depends upon: DEPDIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += lib/librte_eal lib/librte_ether diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index 12fcc23852..0d93331c23 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -61,6 +61,7 @@ #include "virtio_pci.h" #include "virtio_logs.h" #include "virtqueue.h" +#include "virtio_rxtx.h" static int eth_virtio_dev_init(struct rte_eth_dev *eth_dev); @@ -247,8 +248,8 @@ virtio_dev_queue_release(struct virtqueue *vq) { VIRTIO_WRITE_REG_2(hw, VIRTIO_PCI_QUEUE_SEL, vq->queue_id); VIRTIO_WRITE_REG_4(hw, VIRTIO_PCI_QUEUE_PFN, 0); + rte_free(vq->sw_ring); rte_free(vq); - vq = NULL; } } @@ -291,6 +292,9 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev, dev->data->port_id, queue_idx); vq = rte_zmalloc(vq_name, sizeof(struct virtqueue) + vq_size * sizeof(struct vq_desc_extra), RTE_CACHE_LINE_SIZE); + vq->sw_ring = rte_zmalloc_socket("rxq->sw_ring", + (RTE_PMD_VIRTIO_RX_MAX_BURST + vq_size) * + sizeof(vq->sw_ring[0]), RTE_CACHE_LINE_SIZE, socket_id); } else if (queue_type == VTNET_TQ) { snprintf(vq_name, sizeof(vq_name), "port%d_tvq%d", dev->data->port_id, queue_idx); @@ -307,6 +311,12 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev, PMD_INIT_LOG(ERR, "%s: Can not allocate virtqueue", __func__); return (-ENOMEM); } + if (queue_type == VTNET_RQ && vq->sw_ring == NULL) { + PMD_INIT_LOG(ERR, "%s: Can not allocate RX soft ring", + __func__); + rte_free(vq); + return -ENOMEM; + } vq->hw = hw; vq->port_id = dev->data->port_id; diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c index 68103f8740..4fd75461f6 100644 --- a/drivers/net/virtio/virtio_rxtx.c +++ b/drivers/net/virtio/virtio_rxtx.c @@ -54,6 +54,7 @@ #include "virtio_logs.h" #include "virtio_ethdev.h" #include "virtqueue.h" +#include "virtio_rxtx.h" #ifdef RTE_LIBRTE_VIRTIO_DEBUG_DUMP #define VIRTIO_DUMP_PACKET(m, len) rte_pktmbuf_dump(stdout, m, len) @@ -307,6 +308,10 @@ virtio_dev_vring_start(struct virtqueue *vq, int queue_type) vq->vq_ring.desc[i].flags = VRING_DESC_F_WRITE; } + memset(&vq->fake_mbuf, 0, sizeof(vq->fake_mbuf)); + for (i = 0; i < RTE_PMD_VIRTIO_RX_MAX_BURST; i++) + vq->sw_ring[vq->vq_nentries + i] = &vq->fake_mbuf; + while (!virtqueue_full(vq)) { m = rte_rxmbuf_alloc(vq->mpool); if (m == NULL) @@ -315,8 +320,10 @@ virtio_dev_vring_start(struct virtqueue *vq, int queue_type) /****************************************** * Enqueue allocated buffers * *******************************************/ - error = virtqueue_enqueue_recv_refill(vq, m); - + if (use_simple_rxtx) + error = virtqueue_enqueue_recv_refill_simple(vq, m); + else + error = virtqueue_enqueue_recv_refill(vq, m); if (error) { rte_pktmbuf_free(m); break; diff --git a/drivers/net/virtio/virtio_rxtx.h b/drivers/net/virtio/virtio_rxtx.h new file mode 100644 index 0000000000..7d2d8fe96c --- /dev/null +++ b/drivers/net/virtio/virtio_rxtx.h @@ -0,0 +1,37 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 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. + */ + +#define RTE_PMD_VIRTIO_RX_MAX_BURST 64 + +int virtqueue_enqueue_recv_refill_simple(struct virtqueue *vq, + struct rte_mbuf *m); diff --git a/drivers/net/virtio/virtio_rxtx_simple.c b/drivers/net/virtio/virtio_rxtx_simple.c new file mode 100644 index 0000000000..cac5b9f17d --- /dev/null +++ b/drivers/net/virtio/virtio_rxtx_simple.c @@ -0,0 +1,84 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 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 "virtio_logs.h" +#include "virtio_ethdev.h" +#include "virtqueue.h" +#include "virtio_rxtx.h" + +int __attribute__((cold)) +virtqueue_enqueue_recv_refill_simple(struct virtqueue *vq, + struct rte_mbuf *cookie) +{ + struct vq_desc_extra *dxp; + struct vring_desc *start_dp; + uint16_t desc_idx; + + desc_idx = vq->vq_avail_idx & (vq->vq_nentries - 1); + dxp = &vq->vq_descx[desc_idx]; + dxp->cookie = (void *)cookie; + vq->sw_ring[desc_idx] = cookie; + + start_dp = vq->vq_ring.desc; + start_dp[desc_idx].addr = (uint64_t)((uintptr_t)cookie->buf_physaddr + + RTE_PKTMBUF_HEADROOM - sizeof(struct virtio_net_hdr)); + start_dp[desc_idx].len = cookie->buf_len - + RTE_PKTMBUF_HEADROOM + sizeof(struct virtio_net_hdr); + + vq->vq_free_cnt--; + vq->vq_avail_idx++; + + return 0; +} diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h index 7789411a8a..6a1ec48b86 100644 --- a/drivers/net/virtio/virtqueue.h +++ b/drivers/net/virtio/virtqueue.h @@ -190,6 +190,10 @@ struct virtqueue { uint16_t vq_avail_idx; phys_addr_t virtio_net_hdr_mem; /**< hdr for each xmit packet */ + struct rte_mbuf **sw_ring; /**< RX software ring. */ + /* dummy mbuf, for wraparound when processing RX ring. */ + struct rte_mbuf fake_mbuf; + /* Statistics */ uint64_t packets; uint64_t bytes;