On 09.08.2017 15:35, Bodireddy, Bhanuprakash wrote:
>>>
>>> +static int
>>> +netdev_dpdk_vhost_tx_burst(struct netdev_dpdk *dev, int qid) {
>>> +    struct dpdk_tx_queue *txq = &dev->tx_q[qid];
>>> +    struct rte_mbuf **cur_pkts = (struct rte_mbuf
>>> +**)txq->vhost_burst_pkts;
>>> +
>>> +    int tx_vid = netdev_dpdk_get_vid(dev);
>>> +    int tx_qid = qid * VIRTIO_QNUM + VIRTIO_RXQ;
>>> +    uint32_t sent = 0;
>>> +    uint32_t retries = 0;
>>> +    uint32_t sum, total_pkts;
>>> +
>>> +    total_pkts = sum = txq->vhost_pkt_cnt;
>>> +    do {
>>> +        uint32_t ret;
>>> +        ret = rte_vhost_enqueue_burst(tx_vid, tx_qid, &cur_pkts[sent],
>> sum);
>>> +        if (OVS_UNLIKELY(!ret)) {
>>> +            /* No packets enqueued - do not retry. */
>>> +            break;
>>> +        } else {
>>> +            /* Packet have been sent. */
>>> +            sent += ret;
>>> +
>>> +            /* 'sum' packet have to be retransmitted. */
>>> +            sum -= ret;
>>> +        }
>>> +    } while (sum && (retries++ < VHOST_ENQ_RETRY_NUM));
>>> +
>>> +    for (int i = 0; i < total_pkts; i++) {
>>> +        dp_packet_delete(txq->vhost_burst_pkts[i]);
>>> +    }
>>> +
>>> +    /* Reset pkt count. */
>>> +    txq->vhost_pkt_cnt = 0;
>>> +
>>> +    /* 'sum' refers to packets dropped. */
>>> +    return sum;
>>> +}
>>> +
>>> +/* Flush the txq if there are any packets available. */ static int
>>> +netdev_dpdk_vhost_txq_flush(struct netdev *netdev, int qid,
>>> +                            bool concurrent_txq OVS_UNUSED) {
>>> +    struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
>>> +    struct dpdk_tx_queue *txq;
>>> +
>>> +    qid = dev->tx_q[qid % netdev->n_txq].map;
>>> +
>>> +    /* The qid may be disabled in the guest and has been set to
>>> +     * OVS_VHOST_QUEUE_DISABLED.
>>> +     */
>>> +    if (OVS_UNLIKELY(qid < 0)) {
>>> +        return 0;
>>> +    }
>>> +
>>> +    txq = &dev->tx_q[qid];
>>> +    /* Increment the drop count and free the memory. */
>>> +    if (OVS_UNLIKELY(!is_vhost_running(dev) ||
>>> +                     !(dev->flags & NETDEV_UP))) {
>>> +
>>> +        if (txq->vhost_pkt_cnt) {
>>> +            rte_spinlock_lock(&dev->stats_lock);
>>> +            dev->stats.tx_dropped+= txq->vhost_pkt_cnt;
>>> +            rte_spinlock_unlock(&dev->stats_lock);
>>> +
>>> +            for (int i = 0; i < txq->vhost_pkt_cnt; i++) {
>>> +                dp_packet_delete(txq->vhost_burst_pkts[i]);
>>
>> Spinlock (tx_lock) must be held here to avoid queue and mempool breakage.
> 
> I think you are right. tx_lock might be acquired for freeing the packets.

I think that 'vhost_pkt_cnt' reads and updates also should be protected to 
avoid races.

> ---------------------------------------------------------------------------
>     rte_spinlock_lock(&dev->tx_q[qid].tx_lock);
>     for (int i = 0; i < txq->vhost_pkt_cnt; i++) {
>              dp_packet_delete(txq->vhost_burst_pkts[i]);
>     }
>     rte_spinlock_unlock(&dev->tx_q[qid].tx_lock);
> 
> - Bhanuprakash
> 
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to