> -----Original Message----- > From: Bie, Tiwei > Sent: Wednesday, December 6, 2017 7:23 PM > To: Wang, Xiao W <xiao.w.w...@intel.com> > Cc: y...@fridaylinux.org; dev@dpdk.org; step...@networkplumber.org > Subject: Re: [PATCH v2 2/2] net/virtio: support GUEST ANNOUNCE > > On Mon, Dec 04, 2017 at 06:02:08AM -0800, Xiao Wang wrote: > [...] > > diff --git a/drivers/net/virtio/virtio_rxtx.c > > b/drivers/net/virtio/virtio_rxtx.c > > index 6a24fde..7313bdd 100644 > > --- a/drivers/net/virtio/virtio_rxtx.c > > +++ b/drivers/net/virtio/virtio_rxtx.c > > @@ -1100,3 +1100,84 @@ > > > > return nb_tx; > > } > > + > > +uint16_t > > +virtio_inject_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t > nb_pkts) > > +{ > > + struct virtnet_tx *txvq = tx_queue; > > + struct virtqueue *vq = txvq->vq; > > + struct virtio_hw *hw = vq->hw; > > + uint16_t hdr_size = hw->vtnet_hdr_size; > > + uint16_t nb_used, nb_tx = 0; > > + > > + if (unlikely(nb_pkts < 1)) > > + return nb_pkts; > > + > > + PMD_TX_LOG(DEBUG, "%d packets to xmit", nb_pkts); > > + nb_used = VIRTQUEUE_NUSED(vq); > > + > > + virtio_rmb(); > > + if (likely(nb_used > vq->vq_nentries - vq->vq_free_thresh)) > > + virtio_xmit_cleanup(vq, nb_used); > > + > > + for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) { > > + struct rte_mbuf *txm = tx_pkts[nb_tx]; > > + int can_push = 0, use_indirect = 0, slots, need; > > + > > + /* optimize ring usage */ > > + if ((vtpci_with_feature(hw, VIRTIO_F_ANY_LAYOUT) || > > + vtpci_with_feature(hw, > VIRTIO_F_VERSION_1)) && > > + rte_mbuf_refcnt_read(txm) == 1 && > > + RTE_MBUF_DIRECT(txm) && > > + txm->nb_segs == 1 && > > + rte_pktmbuf_headroom(txm) >= hdr_size && > > + rte_is_aligned(rte_pktmbuf_mtod(txm, char *), > > + __alignof__(struct virtio_net_hdr_mrg_rxbuf))) > > + can_push = 1; > > + else if (vtpci_with_feature(hw, > VIRTIO_RING_F_INDIRECT_DESC) && > > + txm->nb_segs < VIRTIO_MAX_TX_INDIRECT) > > + use_indirect = 1; > > + > > + /* How many main ring entries are needed to this Tx? > > + * any_layout => number of segments > > + * indirect => 1 > > + * default => number of segments + 1 > > + */ > > + slots = use_indirect ? 1 : (txm->nb_segs + !can_push); > > + need = slots - vq->vq_free_cnt; > > + > > + /* Positive value indicates it need free vring descriptors */ > > + if (unlikely(need > 0)) { > > + nb_used = VIRTQUEUE_NUSED(vq); > > + virtio_rmb(); > > + need = RTE_MIN(need, (int)nb_used); > > + > > + virtio_xmit_cleanup(vq, need); > > + need = slots - vq->vq_free_cnt; > > + if (unlikely(need > 0)) { > > + PMD_TX_LOG(ERR, > > + "No free tx descriptors to > transmit"); > > + break; > > + } > > + } > > + > > + /* Enqueue Packet buffers */ > > + virtqueue_enqueue_xmit(txvq, txm, slots, use_indirect, > can_push); > > + > > + txvq->stats.bytes += txm->pkt_len; > > + virtio_update_packet_stats(&txvq->stats, txm); > > + } > > + > > + txvq->stats.packets += nb_tx; > > + > > + if (likely(nb_tx)) { > > + vq_update_avail_idx(vq); > > + > > + if (unlikely(virtqueue_kick_prepare(vq))) { > > + virtqueue_notify(vq); > > + PMD_TX_LOG(DEBUG, "Notified backend after xmit"); > > + } > > + } > > + > > + return nb_tx; > > +} > > Simple Tx has some special assumptions and setups of the txq. > Basically the current implementation of virtio_inject_pkts() > is a mirror of virtio_xmit_pkts(). So when simple Tx function > is chosen, calling virtio_inject_pkts() could cause problems.
I will have a static mbuf ** pointer for rarp packets in next version, which can also avoid code duplication. BRs, Xiao