On 10/19/2015 1:16 PM, Stephen Hemminger wrote:
> The space check for transmit ring only needs a single conditional.
> I.e only need to recheck for space if there was no space in first check.
I see you reorganized the code. It is more clear and readable with your
change, but no check is removed.
We could remove the check after virtio_xmit_cleanup. In current
implementation, we assume the virtio_xmit_cleanup and vq_ring_free_chain
always succeed.
> This can help performance and simplifies loop.
>
> Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>
> ---
>  drivers/net/virtio/virtio_rxtx.c | 66 
> ++++++++++++++++------------------------
>  1 file changed, 27 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/net/virtio/virtio_rxtx.c 
> b/drivers/net/virtio/virtio_rxtx.c
> index c5b53bb..5b50ed0 100644
> --- a/drivers/net/virtio/virtio_rxtx.c
> +++ b/drivers/net/virtio/virtio_rxtx.c
> @@ -745,7 +745,6 @@ uint16_t
>  virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
>  {
>       struct virtqueue *txvq = tx_queue;
> -     struct rte_mbuf *txm;
>       uint16_t nb_used, nb_tx;
>       int error;
>  
> @@ -759,57 +758,46 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf 
> **tx_pkts, uint16_t nb_pkts)
>       if (likely(nb_used > txvq->vq_nentries - txvq->vq_free_thresh))
>               virtio_xmit_cleanup(txvq, nb_used);
>  
> -     nb_tx = 0;
> +     for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
> +             struct rte_mbuf *txm = tx_pkts[nb_tx];
> +             int need = txm->nb_segs - txvq->vq_free_cnt + 1;
>  
> -     while (nb_tx < nb_pkts) {
> -             /* Need one more descriptor for virtio header. */
> -             int need = tx_pkts[nb_tx]->nb_segs - txvq->vq_free_cnt + 1;
> -
> -             /*Positive value indicates it need free vring descriptors */
> +             /* Positive value indicates it need free vring descriptors */
As you fix the comment, if it is correct, could you do s/need/needs/ as
well, :)?
>               if (unlikely(need > 0)) {
>                       nb_used = VIRTQUEUE_NUSED(txvq);
>                       virtio_rmb();
>                       need = RTE_MIN(need, (int)nb_used);
>  
>                       virtio_xmit_cleanup(txvq, need);
> -                     need = (int)tx_pkts[nb_tx]->nb_segs -
> -                             txvq->vq_free_cnt + 1;
> -             }
> -
> -             /*
> -              * Zero or negative value indicates it has enough free
> -              * descriptors to use for transmitting.
> -              */
> -             if (likely(need <= 0)) {
> -                     txm = tx_pkts[nb_tx];
> -
> -                     /* Do VLAN tag insertion */
> -                     if (unlikely(txm->ol_flags & PKT_TX_VLAN_PKT)) {
> -                             error = rte_vlan_insert(&txm);
> -                             if (unlikely(error)) {
> -                                     rte_pktmbuf_free(txm);
> -                                     ++nb_tx;
> -                                     continue;
> -                             }
Still need is rechecked here. It could be removed if virtio_xmit_cleanup
ensures need would be <= 0 after the call.
> +                     need = txm->nb_segs - txvq->vq_free_cnt + 1;
> +                     if (unlikely(need > 0)) {
> +                             PMD_TX_LOG(ERR,
> +                                        "No free tx descriptors to 
> transmit");
> +                             break;
>                       }
> +             }
>  
> -                     /* Enqueue Packet buffers */
> -                     error = virtqueue_enqueue_xmit(txvq, txm);
> +             /* Do VLAN tag insertion */
> +             if (unlikely(txm->ol_flags & PKT_TX_VLAN_PKT)) {
> +                     error = rte_vlan_insert(&txm);
>                       if (unlikely(error)) {
> -                             if (error == ENOSPC)
> -                                     PMD_TX_LOG(ERR, "virtqueue_enqueue Free 
> count = 0");
> -                             else if (error == EMSGSIZE)
> -                                     PMD_TX_LOG(ERR, "virtqueue_enqueue Free 
> count < 1");
> -                             else
> -                                     PMD_TX_LOG(ERR, "virtqueue_enqueue 
> error: %d", error);
> -                             break;
> +                             rte_pktmbuf_free(txm);
> +                             continue;
>                       }
> -                     nb_tx++;
> -                     txvq->bytes += txm->pkt_len;
> -             } else {
> -                     PMD_TX_LOG(ERR, "No free tx descriptors to transmit");
> +             }
> +
> +             /* Enqueue Packet buffers */
> +             error = virtqueue_enqueue_xmit(txvq, txm);
> +             if (unlikely(error)) {
> +                     if (error == ENOSPC)
> +                             PMD_TX_LOG(ERR, "virtqueue_enqueue Free count = 
> 0");
> +                     else if (error == EMSGSIZE)
> +                             PMD_TX_LOG(ERR, "virtqueue_enqueue Free count < 
> 1");
> +                     else
> +                             PMD_TX_LOG(ERR, "virtqueue_enqueue error: %d", 
> error);
>                       break;
>               }
> +             txvq->bytes += txm->pkt_len;
>       }
>  
>       txvq->packets += nb_tx;

Reply via email to