This patch introduces function 'netdev_dpdk_filter_packet_len()' which is intended to find and remove all packets with 'pkt_len > max_packet_len' from the Tx batch.
It fixes inaccurate counting of 'tx_bytes' in vHost case if there was dropped packets and allows to simplify send function. Fixes: 0072e931b207 ("netdev-dpdk: add support for jumbo frames") Signed-off-by: Ilya Maximets <i.maxim...@samsung.com> --- lib/netdev-dpdk.c | 52 +++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index e5f2cdd..59ae32e 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -1435,6 +1435,28 @@ netdev_dpdk_qos_run__(struct netdev_dpdk *dev, struct rte_mbuf **pkts, return cnt; } +static int +netdev_dpdk_filter_packet_len(struct netdev_dpdk *dev, struct rte_mbuf **pkts, + int pkt_cnt) +{ + int i = 0; + int cnt = 0; + struct rte_mbuf *pkt; + + for (i = 0; i < pkt_cnt; i++) { + pkt = pkts[i]; + if (OVS_UNLIKELY(pkt->pkt_len > dev->max_packet_len)) { + VLOG_WARN_RL(&rl, "%s: Too big size %" PRIu32 " max_packet_len %d", + dev->up.name, pkt->pkt_len, dev->max_packet_len); + rte_pktmbuf_free(pkt); + } else if (i != cnt++) { + pkts[cnt - 1] = pkt; + } + } + + return cnt; +} + static inline void netdev_dpdk_vhost_update_tx_counters(struct netdev_stats *stats, struct dp_packet **packets, @@ -1459,8 +1481,7 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); struct rte_mbuf **cur_pkts = (struct rte_mbuf **) pkts; unsigned int total_pkts = cnt; - unsigned int qos_pkts = 0; - unsigned int mtu_dropped = 0; + unsigned int dropped = 0; int i, retries = 0; qid = dev->tx_q[qid % netdev->n_txq].map; @@ -1475,52 +1496,37 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, rte_spinlock_lock(&dev->tx_q[qid].tx_lock); + cnt = netdev_dpdk_filter_packet_len(dev, cur_pkts, cnt); /* Check has QoS has been configured for the netdev */ cnt = netdev_dpdk_qos_run__(dev, cur_pkts, cnt); - qos_pkts = total_pkts - cnt; + dropped = total_pkts - cnt; do { int vhost_qid = qid * VIRTIO_QNUM + VIRTIO_RXQ; unsigned int tx_pkts; - unsigned int try_tx_pkts = cnt; - for (i = 0; i < cnt; i++) { - if (cur_pkts[i]->pkt_len > dev->max_packet_len) { - try_tx_pkts = i; - break; - } - } - if (!try_tx_pkts) { - cur_pkts++; - mtu_dropped++; - cnt--; - continue; - } tx_pkts = rte_vhost_enqueue_burst(netdev_dpdk_get_vid(dev), - vhost_qid, cur_pkts, try_tx_pkts); + vhost_qid, cur_pkts, cnt); if (OVS_LIKELY(tx_pkts)) { /* Packets have been sent.*/ cnt -= tx_pkts; /* Prepare for possible retry.*/ cur_pkts = &cur_pkts[tx_pkts]; - if (tx_pkts != try_tx_pkts) { - retries++; - } } else { /* No packets sent - do not retry.*/ break; } - } while (cnt && (retries <= VHOST_ENQ_RETRY_NUM)); + } while (cnt && (retries++ <= VHOST_ENQ_RETRY_NUM)); rte_spinlock_unlock(&dev->tx_q[qid].tx_lock); rte_spinlock_lock(&dev->stats_lock); netdev_dpdk_vhost_update_tx_counters(&dev->stats, pkts, total_pkts, - cnt + mtu_dropped + qos_pkts); + cnt + dropped); rte_spinlock_unlock(&dev->stats_lock); out: - for (i = 0; i < total_pkts - qos_pkts; i++) { + for (i = 0; i < total_pkts - dropped; i++) { dp_packet_delete(pkts[i]); } } -- 2.7.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev