X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=drivers%2Fnet%2Fvirtio%2Fvirtqueue.c;h=0e9e03c74ea67f92690ddcfba2d5da3206ee7352;hb=39157ec04095ab012d11db23c462844634bfbb8f;hp=7f60e3ef1a2cc7f619ac88312353ec235f704311;hpb=97f17497d162afdb82c8704bf097f0fee3724b2e;p=deb_dpdk.git diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c index 7f60e3ef..0e9e03c7 100644 --- a/drivers/net/virtio/virtqueue.c +++ b/drivers/net/virtio/virtqueue.c @@ -37,6 +37,7 @@ #include "virtqueue.h" #include "virtio_logs.h" #include "virtio_pci.h" +#include "virtio_rxtx_simple.h" void virtqueue_disable_intr(struct virtqueue *vq) @@ -55,18 +56,81 @@ virtqueue_disable_intr(struct virtqueue *vq) * 2) mbuf that hasn't been consued by backend. */ struct rte_mbuf * -virtqueue_detatch_unused(struct virtqueue *vq) +virtqueue_detach_unused(struct virtqueue *vq) { struct rte_mbuf *cookie; - int idx; + struct virtio_hw *hw; + uint16_t start, end; + int type, idx; - if (vq != NULL) - for (idx = 0; idx < vq->vq_nentries; idx++) { + if (vq == NULL) + return NULL; + + hw = vq->hw; + type = virtio_get_queue_type(hw, vq->vq_queue_index); + start = vq->vq_avail_idx & (vq->vq_nentries - 1); + end = (vq->vq_avail_idx + vq->vq_free_cnt) & (vq->vq_nentries - 1); + + for (idx = 0; idx < vq->vq_nentries; idx++) { + if (hw->use_simple_rxtx && type == VTNET_RQ) { + if (start <= end && idx >= start && idx < end) + continue; + if (start > end && (idx >= start || idx < end)) + continue; + cookie = vq->sw_ring[idx]; + if (cookie != NULL) { + vq->sw_ring[idx] = NULL; + return cookie; + } + } else { cookie = vq->vq_descx[idx].cookie; if (cookie != NULL) { vq->vq_descx[idx].cookie = NULL; return cookie; } } + } + return NULL; } + +/* Flush the elements in the used ring. */ +void +virtqueue_rxvq_flush(struct virtqueue *vq) +{ + struct virtnet_rx *rxq = &vq->rxq; + struct virtio_hw *hw = vq->hw; + struct vring_used_elem *uep; + struct vq_desc_extra *dxp; + uint16_t used_idx, desc_idx; + uint16_t nb_used, i; + + nb_used = VIRTQUEUE_NUSED(vq); + + for (i = 0; i < nb_used; i++) { + used_idx = vq->vq_used_cons_idx & (vq->vq_nentries - 1); + uep = &vq->vq_ring.used->ring[used_idx]; + if (hw->use_simple_rxtx) { + desc_idx = used_idx; + rte_pktmbuf_free(vq->sw_ring[desc_idx]); + vq->vq_free_cnt++; + } else { + desc_idx = (uint16_t)uep->id; + dxp = &vq->vq_descx[desc_idx]; + if (dxp->cookie != NULL) { + rte_pktmbuf_free(dxp->cookie); + dxp->cookie = NULL; + } + vq_ring_free_chain(vq, desc_idx); + } + vq->vq_used_cons_idx++; + } + + if (hw->use_simple_rxtx) { + while (vq->vq_free_cnt >= RTE_VIRTIO_VPMD_RX_REARM_THRESH) { + virtio_rxq_rearm_vec(rxq); + if (virtqueue_kick_prepare(vq)) + virtqueue_notify(vq); + } + } +}