aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/dpdk/device/device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/dpdk/device/device.c')
-rw-r--r--src/plugins/dpdk/device/device.c66
1 files changed, 44 insertions, 22 deletions
diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c
index c5abbd5f727..58ad4fda0d1 100644
--- a/src/plugins/dpdk/device/device.c
+++ b/src/plugins/dpdk/device/device.c
@@ -159,7 +159,7 @@ tx_burst_vector_internal (vlib_main_t *vm, dpdk_device_t *xd,
{
dpdk_tx_queue_t *txq;
u32 n_retry;
- int n_sent = 0;
+ u32 n_sent = 0;
n_retry = 16;
txq = vec_elt_at_index (xd->tx_queues, queue_id);
@@ -279,9 +279,11 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm,
vnet_hw_if_tx_frame_t *tf = vlib_frame_scalar_args (f);
u32 n_packets = f->n_vectors;
u32 n_left;
+ u32 n_prep;
u32 thread_index = vm->thread_index;
int queue_id = tf->queue_id;
u8 is_shared = tf->shared_queue;
+ u8 offload_enabled = 0;
u32 tx_pkts = 0;
dpdk_per_thread_data_t *ptd = vec_elt_at_index (dm->per_thread_data,
thread_index);
@@ -333,6 +335,7 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm,
if (PREDICT_FALSE ((xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD) &&
(or_flags & VNET_BUFFER_F_OFFLOAD)))
{
+ offload_enabled = 1;
dpdk_buffer_tx_offload (xd, b[0], mb[0]);
dpdk_buffer_tx_offload (xd, b[1], mb[1]);
dpdk_buffer_tx_offload (xd, b[2], mb[2]);
@@ -386,6 +389,7 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm,
if (PREDICT_FALSE ((xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD) &&
(or_flags & VNET_BUFFER_F_OFFLOAD)))
{
+ offload_enabled = 1;
dpdk_buffer_tx_offload (xd, b[0], mb[0]);
dpdk_buffer_tx_offload (xd, b[1], mb[1]);
}
@@ -408,7 +412,13 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm,
b[0] = vlib_buffer_from_rte_mbuf (mb[0]);
dpdk_validate_rte_mbuf (vm, b[0], 1);
- dpdk_buffer_tx_offload (xd, b[0], mb[0]);
+
+ if (PREDICT_FALSE ((xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD) &&
+ (b[0]->flags & VNET_BUFFER_F_OFFLOAD)))
+ {
+ offload_enabled = 1;
+ dpdk_buffer_tx_offload (xd, b[0], mb[0]);
+ }
if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
if (b[0]->flags & VLIB_BUFFER_IS_TRACED)
@@ -418,32 +428,44 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm,
n_left--;
}
- /* transmit as many packets as possible */
+ /* prepare and transmit as many packets as possible */
tx_pkts = n_packets = mb - ptd->mbufs;
- n_left = tx_burst_vector_internal (vm, xd, ptd->mbufs, n_packets, queue_id,
- is_shared);
+ n_prep = n_packets;
- {
- /* If there is no callback then drop any non-transmitted packets */
- if (PREDICT_FALSE (n_left))
- {
- tx_pkts -= n_left;
- vlib_simple_counter_main_t *cm;
- vnet_main_t *vnm = vnet_get_main ();
+ if (PREDICT_FALSE (offload_enabled &&
+ (xd->flags & DPDK_DEVICE_FLAG_TX_PREPARE)))
+ {
+ n_prep =
+ rte_eth_tx_prepare (xd->port_id, queue_id, ptd->mbufs, n_packets);
- cm = vec_elt_at_index (vnm->interface_main.sw_if_counters,
- VNET_INTERFACE_COUNTER_TX_ERROR);
+ /* If mbufs are malformed then drop any non-prepared packets */
+ if (PREDICT_FALSE (n_prep != n_packets))
+ {
+ n_left = n_packets - n_prep;
+ }
+ }
- vlib_increment_simple_counter (cm, thread_index, xd->sw_if_index,
- n_left);
+ n_left +=
+ tx_burst_vector_internal (vm, xd, ptd->mbufs, n_prep, queue_id, is_shared);
- vlib_error_count (vm, node->node_index, DPDK_TX_FUNC_ERROR_PKT_DROP,
- n_left);
+ /* If there is no callback then drop any non-transmitted packets */
+ if (PREDICT_FALSE (n_left))
+ {
+ tx_pkts -= n_left;
+ vlib_simple_counter_main_t *cm;
+ vnet_main_t *vnm = vnet_get_main ();
- while (n_left--)
- rte_pktmbuf_free (ptd->mbufs[n_packets - n_left - 1]);
- }
- }
+ cm = vec_elt_at_index (vnm->interface_main.sw_if_counters,
+ VNET_INTERFACE_COUNTER_TX_ERROR);
+
+ vlib_increment_simple_counter (cm, thread_index, xd->sw_if_index,
+ n_left);
+
+ vlib_error_count (vm, node->node_index, DPDK_TX_FUNC_ERROR_PKT_DROP,
+ n_left);
+
+ rte_pktmbuf_free_bulk (&ptd->mbufs[tx_pkts], n_left);
+ }
return tx_pkts;
}