#include <string.h>
#include <errno.h>
+#include <rte_cycles.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_branch_prediction.h>
PMD_INIT_FUNC_TRACE();
/*
- * Reinitialise since virtio port might have been stopped and restarted
- */
+ * Reinitialise since virtio port might have been stopped and restarted
+ */
memset(vq->vq_ring_virt_mem, 0, vq->vq_ring_size);
vring_init(vr, size, ring_mem, vq->vq_alignment);
vq->vq_used_cons_idx = 0;
vq->vq_desc_head_idx = 0;
+ vq->vq_avail_idx = 0;
+ vq->vq_desc_tail_idx = vq->vq_nentries - 1;
vq->vq_free_cnt = vq->vq_nentries;
memset(vq->vq_descx, 0, sizeof(struct vq_desc_extra) * vq->vq_nentries);
}
nbufs++;
}
+ vq_update_avail_idx(vq);
PMD_INIT_LOG(DEBUG, "Allocated %d bufs\n", nbufs);
VIRTIO_WRITE_REG_2(vq->hw, VIRTIO_PCI_QUEUE_SEL, VTNET_SQ_RQ_QUEUE_IDX);
VIRTIO_WRITE_REG_4(vq->hw, VIRTIO_PCI_QUEUE_PFN,
}
#define VIRTIO_MBUF_BURST_SZ 64
+#define DESC_PER_CACHELINE (CACHE_LINE_SIZE / sizeof(struct vring_desc))
uint16_t
virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
{
num = (uint16_t)(likely(nb_used <= nb_pkts) ? nb_used : nb_pkts);
num = (uint16_t)(likely(num <= VIRTIO_MBUF_BURST_SZ) ? num : VIRTIO_MBUF_BURST_SZ);
+ if (likely(num > DESC_PER_CACHELINE))
+ num = num - ((rxvq->vq_used_cons_idx + num) % DESC_PER_CACHELINE);
if(num == 0) return 0;
- num = virtqueue_dequeue_burst(rxvq, rcv_pkts, len, num);
+ num = virtqueue_dequeue_burst_rx(rxvq, rcv_pkts, len, num);
PMD_RX_LOG(DEBUG, "used:%d dequeue:%d\n", nb_used, num);
for (i = 0; i < num ; i ++) {
rxm = rcv_pkts[i];
PMD_RX_LOG(DEBUG, "Notified\n");
}
}
+ vq_update_avail_idx(rxvq);
+
return (nb_rx);
}
{
struct virtqueue *txvq = tx_queue;
struct rte_mbuf *txm;
- uint16_t nb_used, nb_tx, count, num, i;
+ uint16_t nb_used, nb_tx, num;
int error;
- uint32_t len[VIRTIO_MBUF_BURST_SZ];
- struct rte_mbuf *snd_pkts[VIRTIO_MBUF_BURST_SZ];
struct virtio_hw *hw;
- nb_tx = count = 0;
+ nb_tx = 0;
if (unlikely(nb_pkts < 1))
return (nb_pkts);
hw = txvq->hw;
num = (uint16_t)(likely(nb_used < VIRTIO_MBUF_BURST_SZ) ? nb_used : VIRTIO_MBUF_BURST_SZ);
- num = virtqueue_dequeue_burst(txvq, snd_pkts, len, num);
- for (i = 0; i < num ; i ++) {
- rte_pktmbuf_free_seg(snd_pkts[i]);
- }
- while (count++ < nb_pkts) {
+ while (nb_tx < nb_pkts) {
+ if (virtqueue_full(txvq) && num) {
+ virtqueue_dequeue_pkt_tx(txvq);
+ num--;
+ }
if(!virtqueue_full(txvq)) {
txm = tx_pkts[nb_tx];
- /************************************************/
- /***** Enqueue Packet buffers *****/
- /************************************************/
+ /* Enqueue Packet buffers */
error = virtqueue_enqueue_xmit(txvq, txm);
if (unlikely(error)) {
- // rte_pktmbuf_free_seg(txm); /* the upper application will free this packet */
if (error == ENOSPC)
PMD_TX_LOG(ERR, "virtqueue_enqueue Free count = 0\n");
else if (error == EMSGSIZE)
hw->eth_stats.obytes += txm->pkt.data_len;
} else {
PMD_TX_LOG(ERR, "No free tx descriptors to transmit\n");
- virtqueue_notify(txvq);
break;
}
}
+ vq_update_avail_idx(txvq);
+
hw->eth_stats.opackets += nb_tx;
if(unlikely(virtqueue_kick_prepare(txvq))) {