From patchwork Thu Apr 5 10:10:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Freimann X-Patchwork-Id: 37279 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 5281E1CB0A; Thu, 5 Apr 2018 12:11:43 +0200 (CEST) Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by dpdk.org (Postfix) with ESMTP id B37CB1CB01 for ; Thu, 5 Apr 2018 12:11:39 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5641140201A4; Thu, 5 Apr 2018 10:11:39 +0000 (UTC) Received: from localhost (dhcp-192-241.str.redhat.com [10.33.192.241]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CD6B0A9A1C; Thu, 5 Apr 2018 10:11:32 +0000 (UTC) From: Jens Freimann To: dev@dpdk.org Cc: tiwei.bie@intel.com, yliu@fridaylinux.org, maxime.coquelin@redhat.com, mst@redhat.com Date: Thu, 5 Apr 2018 12:10:28 +0200 Message-Id: <20180405101031.26468-19-jfreimann@redhat.com> In-Reply-To: <20180405101031.26468-1-jfreimann@redhat.com> References: <20180405101031.26468-1-jfreimann@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Thu, 05 Apr 2018 10:11:39 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Thu, 05 Apr 2018 10:11:39 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jfreimann@redhat.com' RCPT:'' Subject: [dpdk-dev] [PATCH v3 18/21] net/virtio: add support for mergeable buffers with packed virtqueues 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Implement support for receiving merged buffers in virtio when packed virtqueues are enabled. Signed-off-by: Jens Freimann --- drivers/net/virtio/virtio_ethdev.c | 10 ++-- drivers/net/virtio/virtio_rxtx.c | 107 +++++++++++++++++++++++++++++++++---- drivers/net/virtio/virtqueue.h | 1 + 3 files changed, 104 insertions(+), 14 deletions(-) diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index 7367d9c5d..a3c3376d7 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -1322,15 +1322,15 @@ set_rxtx_funcs(struct rte_eth_dev *eth_dev) { struct virtio_hw *hw = eth_dev->data->dev_private; - /* workarount for packed vqs which don't support mrg_rxbuf at this point */ - if (vtpci_packed_queue(hw) && vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) { - eth_dev->rx_pkt_burst = &virtio_recv_pkts_packed; - } else if (hw->use_simple_rx) { + if (hw->use_simple_rx) { PMD_INIT_LOG(INFO, "virtio: using simple Rx path on port %u", eth_dev->data->port_id); eth_dev->rx_pkt_burst = virtio_recv_pkts_vec; } else if (vtpci_packed_queue(hw)) { - eth_dev->rx_pkt_burst = &virtio_recv_pkts_packed; + if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) + eth_dev->rx_pkt_burst = &virtio_recv_mergeable_pkts; + else + eth_dev->rx_pkt_burst = &virtio_recv_pkts_packed; } else if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) { PMD_INIT_LOG(INFO, "virtio: using mergeable buffer Rx path on port %u", diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c index 9220ae661..a48ca6aaa 100644 --- a/drivers/net/virtio/virtio_rxtx.c +++ b/drivers/net/virtio/virtio_rxtx.c @@ -155,8 +155,8 @@ vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx) vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt + dxp->ndescs); if ((dp->flags & VRING_DESC_F_INDIRECT) == 0) { while (dp->flags & VRING_DESC_F_NEXT) { - desc_idx_last = dp->next; - dp = &vq->vq_ring.desc[dp->next]; + desc_idx_last = desc_idx++; + dp = &vq->vq_ring.desc[desc_idx]; } } dxp->ndescs = 0; @@ -177,6 +177,76 @@ vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx) dp->next = VQ_RING_DESC_CHAIN_END; } +static void +virtio_refill_packed(struct virtqueue *vq, uint16_t used_idx, struct virtnet_rx *rxvq) +{ + struct vq_desc_extra *dxp; + struct vring_desc_packed *descs = vq->vq_ring.desc_packed; + struct vring_desc_packed *desc; + struct rte_mbuf *nmb; + + nmb = rte_mbuf_raw_alloc(rxvq->mpool); + if (unlikely(nmb == NULL)) { + struct rte_eth_dev *dev + = &rte_eth_devices[rxvq->port_id]; + dev->data->rx_mbuf_alloc_failed++; + return; + } + + desc = &descs[used_idx & (vq->vq_nentries - 1)]; + + dxp = &vq->vq_descx[used_idx & (vq->vq_nentries - 1)]; + + dxp->cookie = nmb; + dxp->ndescs = 1; + + desc->addr = VIRTIO_MBUF_ADDR(nmb, vq) + + RTE_PKTMBUF_HEADROOM - vq->hw->vtnet_hdr_size; + desc->len = nmb->buf_len - RTE_PKTMBUF_HEADROOM + + vq->hw->vtnet_hdr_size; + desc->flags |= VRING_DESC_F_WRITE; + + +} + +static uint16_t +virtqueue_dequeue_burst_rx_packed(struct virtqueue *vq, struct rte_mbuf **rx_pkts, + uint32_t *len, uint16_t num, struct virtnet_rx *rx_queue) +{ + struct rte_mbuf *cookie; + uint16_t used_idx; + struct vring_desc_packed *desc; + uint16_t i; + + for (i = 0; i < num; i++) { + used_idx = (uint16_t)(vq->vq_used_cons_idx & (vq->vq_nentries - 1)); + desc = &vq->vq_ring.desc_packed[used_idx]; + if (!desc_is_used(desc)) + return i; + len[i] = desc->len; + cookie = (struct rte_mbuf *)vq->vq_descx[used_idx].cookie; + + if (unlikely(cookie == NULL)) { + PMD_DRV_LOG(ERR, "vring descriptor with no mbuf cookie at %u", + vq->vq_used_cons_idx); + break; + } + rte_prefetch0(cookie); + rte_packet_prefetch(rte_pktmbuf_mtod(cookie, void *)); + rx_pkts[i] = cookie; + + virtio_refill_packed(vq, used_idx, rx_queue); + + rte_smp_wmb(); + if ((vq->vq_used_cons_idx & (vq->vq_nentries - 1)) == 0) + toggle_wrap_counter(&vq->vq_ring); + set_desc_avail(&vq->vq_ring, desc); + vq->vq_used_cons_idx++; + } + + return i; +} + static uint16_t virtqueue_dequeue_burst_rx(struct virtqueue *vq, struct rte_mbuf **rx_pkts, uint32_t *len, uint16_t num) @@ -1066,12 +1136,16 @@ virtio_recv_mergeable_pkts(void *rx_queue, uint32_t seg_res; uint32_t hdr_size; int offload; + uint32_t rx_num = 0; nb_rx = 0; if (unlikely(hw->started == 0)) return nb_rx; - nb_used = VIRTQUEUE_NUSED(vq); + if (vtpci_packed_queue(vq->hw)) + nb_used = VIRTIO_MBUF_BURST_SZ; + else + nb_used = VIRTQUEUE_NUSED(vq); virtio_rmb(); @@ -1085,14 +1159,23 @@ virtio_recv_mergeable_pkts(void *rx_queue, hdr_size = hw->vtnet_hdr_size; offload = rx_offload_enabled(hw); + vq->vq_used_idx = vq->vq_used_cons_idx; + while (i < nb_used) { struct virtio_net_hdr_mrg_rxbuf *header; if (nb_rx == nb_pkts) break; - num = virtqueue_dequeue_burst_rx(vq, rcv_pkts, len, 1); - if (num != 1) + if (vtpci_packed_queue(vq->hw)) + num = virtqueue_dequeue_burst_rx_packed(vq, rcv_pkts, len, 1, + (struct virtnet_rx *) rx_queue); + else + num = virtqueue_dequeue_burst_rx(vq, rcv_pkts, len, 1); + if (num == 0) { + return nb_rx; + } + if (num != 1 ) continue; i++; @@ -1143,9 +1226,13 @@ virtio_recv_mergeable_pkts(void *rx_queue, uint16_t rcv_cnt = RTE_MIN(seg_res, RTE_DIM(rcv_pkts)); if (likely(VIRTQUEUE_NUSED(vq) >= rcv_cnt)) { - uint32_t rx_num = - virtqueue_dequeue_burst_rx(vq, - rcv_pkts, len, rcv_cnt); + if (vtpci_packed_queue(vq->hw)) + rx_num = virtqueue_dequeue_burst_rx_packed(vq, + rcv_pkts, len, rcv_cnt, + (struct virtnet_rx *) rx_queue); + else + rx_num = virtqueue_dequeue_burst_rx(vq, + rcv_pkts, len, rcv_cnt); i += rx_num; rcv_cnt = rx_num; } else { @@ -1189,6 +1276,9 @@ virtio_recv_mergeable_pkts(void *rx_queue, rxvq->stats.packets += nb_rx; + if (vtpci_packed_queue(vq->hw)) + return nb_rx; + /* Allocate new mbuf for the used descriptor */ error = ENOSPC; while (likely(!virtqueue_full(vq))) { @@ -1209,7 +1299,6 @@ virtio_recv_mergeable_pkts(void *rx_queue, if (likely(nb_enqueued)) { vq_update_avail_idx(vq); - if (unlikely(virtqueue_kick_prepare(vq))) { virtqueue_notify(vq); PMD_RX_LOG(DEBUG, "Notified"); diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h index 7e265bf93..7196bd717 100644 --- a/drivers/net/virtio/virtqueue.h +++ b/drivers/net/virtio/virtqueue.h @@ -171,6 +171,7 @@ struct virtqueue { * trails vq_ring.used->idx. */ uint16_t vq_used_cons_idx; + uint16_t vq_used_idx; uint16_t vq_nentries; /**< vring desc numbers */ uint16_t vq_free_cnt; /**< num of desc available */ uint16_t vq_avail_idx; /**< sync until needed */