vlib: refactor trajectory trace debug feature
[vpp.git] / src / plugins / dpdk / device / device.c
index 7a86ee0..94b3f6b 100644 (file)
@@ -22,6 +22,7 @@
 #include <dpdk/device/dpdk.h>
 #include <dpdk/device/dpdk_priv.h>
 #include <vppinfra/error.h>
+#include <vlib/unix/unix.h>
 
 #define foreach_dpdk_tx_func_error                     \
   _(BAD_RETVAL, "DPDK tx function returned an error")  \
@@ -218,17 +219,20 @@ static_always_inline void
 dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b,
                        struct rte_mbuf *mb)
 {
-  u32 ip_cksum = b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM;
-  u32 tcp_cksum = b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
-  u32 udp_cksum = b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM;
   int is_ip4 = b->flags & VNET_BUFFER_F_IS_IP4;
-  u32 tso = b->flags & VNET_BUFFER_F_GSO;
+  u32 tso = b->flags & VNET_BUFFER_F_GSO, max_pkt_len;
+  u32 oflags, ip_cksum, tcp_cksum, udp_cksum;
   u64 ol_flags;
 
   /* Is there any work for us? */
-  if (PREDICT_TRUE ((ip_cksum | tcp_cksum | udp_cksum | tso) == 0))
+  if (PREDICT_TRUE (((b->flags & VNET_BUFFER_F_OFFLOAD) | tso) == 0))
     return;
 
+  oflags = vnet_buffer2 (b)->oflags;
+  ip_cksum = oflags & VNET_BUFFER_OFFLOAD_F_IP_CKSUM;
+  tcp_cksum = oflags & VNET_BUFFER_OFFLOAD_F_TCP_CKSUM;
+  udp_cksum = oflags & VNET_BUFFER_OFFLOAD_F_UDP_CKSUM;
+
   mb->l2_len = vnet_buffer (b)->l3_hdr_offset - b->current_data;
   mb->l3_len = vnet_buffer (b)->l4_hdr_offset -
     vnet_buffer (b)->l3_hdr_offset;
@@ -238,12 +242,15 @@ dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b,
   ol_flags |= ip_cksum ? PKT_TX_IP_CKSUM : 0;
   ol_flags |= tcp_cksum ? PKT_TX_TCP_CKSUM : 0;
   ol_flags |= udp_cksum ? PKT_TX_UDP_CKSUM : 0;
-  ol_flags |= tso ? (tcp_cksum ? PKT_TX_TCP_SEG : PKT_TX_UDP_SEG) : 0;
 
   if (tso)
     {
       mb->l4_len = vnet_buffer2 (b)->gso_l4_hdr_sz;
       mb->tso_segsz = vnet_buffer2 (b)->gso_size;
+      /* ensure packet is large enough to require tso */
+      max_pkt_len = mb->l2_len + mb->l3_len + mb->l4_len + mb->tso_segsz;
+      if (mb->tso_segsz != 0 && mb->pkt_len > max_pkt_len)
+       ol_flags |= (tcp_cksum ? PKT_TX_TCP_SEG : PKT_TX_UDP_SEG);
     }
 
   mb->ol_flags |= ol_flags;
@@ -304,11 +311,6 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm,
       or_flags = b[0]->flags | b[1]->flags | b[2]->flags | b[3]->flags;
       all_or_flags |= or_flags;
 
-      VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]);
-      VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[1]);
-      VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[2]);
-      VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[3]);
-
       if (or_flags & VLIB_BUFFER_NEXT_PRESENT)
        {
          dpdk_validate_rte_mbuf (vm, b[0], 1);
@@ -325,10 +327,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_TCP_CKSUM
-                          | VNET_BUFFER_F_OFFLOAD_IP_CKSUM
-                          | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM))))
+                        (or_flags & VNET_BUFFER_F_OFFLOAD)))
        {
          dpdk_buffer_tx_offload (xd, b[0], mb[0]);
          dpdk_buffer_tx_offload (xd, b[1], mb[1]);
@@ -370,9 +369,6 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm,
       or_flags = b[0]->flags | b[1]->flags;
       all_or_flags |= or_flags;
 
-      VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]);
-      VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[1]);
-
       if (or_flags & VLIB_BUFFER_NEXT_PRESENT)
        {
          dpdk_validate_rte_mbuf (vm, b[0], 1);
@@ -385,10 +381,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_TCP_CKSUM
-                          | VNET_BUFFER_F_OFFLOAD_IP_CKSUM
-                          | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM))))
+                        (or_flags & VNET_BUFFER_F_OFFLOAD)))
        {
          dpdk_buffer_tx_offload (xd, b[0], mb[0]);
          dpdk_buffer_tx_offload (xd, b[1], mb[1]);
@@ -411,7 +404,6 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm,
     {
       b[0] = vlib_buffer_from_rte_mbuf (mb[0]);
       all_or_flags |= b[0]->flags;
-      VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]);
 
       dpdk_validate_rte_mbuf (vm, b[0], 1);
       dpdk_buffer_tx_offload (xd, b[0], mb[0]);
@@ -629,14 +621,14 @@ dpdk_interface_set_rss_queues (struct vnet_main_t *vnm,
 
   valid_queue_count = 0;
   /* *INDENT-OFF* */
-  clib_bitmap_foreach (i, bitmap, ({
+  clib_bitmap_foreach (i, bitmap)  {
     if (i >= dev_info.nb_rx_queues)
       {
         err = clib_error_return (0, "illegal queue number");
         goto done;
       }
     reta[valid_queue_count++] = i;
-  }));
+  }
   /* *INDENT-ON* */
 
   /* check valid_queue_count not zero, make coverity happy */
@@ -694,6 +686,41 @@ done:
   return err;
 }
 
+static clib_error_t *
+dpdk_interface_rx_mode_change (vnet_main_t *vnm, u32 hw_if_index, u32 qid,
+                              vnet_hw_if_rx_mode mode)
+{
+  dpdk_main_t *xm = &dpdk_main;
+  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
+  dpdk_device_t *xd = vec_elt_at_index (xm->devices, hw->dev_instance);
+  clib_file_main_t *fm = &file_main;
+  dpdk_rx_queue_t *rxq;
+  clib_file_t *f;
+  int rv = 0;
+  if (!(xd->flags & DPDK_DEVICE_FLAG_INT_SUPPORTED))
+    return clib_error_return (0, "unsupported op (is the interface up?)", rv);
+  if (mode == VNET_HW_IF_RX_MODE_POLLING &&
+      !(xd->flags & DPDK_DEVICE_FLAG_INT_UNMASKABLE))
+    rv = rte_eth_dev_rx_intr_disable (xd->port_id, qid);
+  else if (mode == VNET_HW_IF_RX_MODE_POLLING)
+    {
+      rxq = vec_elt_at_index (xd->rx_queues, qid);
+      f = pool_elt_at_index (fm->file_pool, rxq->clib_file_index);
+      fm->file_update (f, UNIX_FILE_UPDATE_DELETE);
+    }
+  else if (!(xd->flags & DPDK_DEVICE_FLAG_INT_UNMASKABLE))
+    rv = rte_eth_dev_rx_intr_enable (xd->port_id, qid);
+  else
+    {
+      rxq = vec_elt_at_index (xd->rx_queues, qid);
+      f = pool_elt_at_index (fm->file_pool, rxq->clib_file_index);
+      fm->file_update (f, UNIX_FILE_UPDATE_ADD);
+    }
+  if (rv)
+    return clib_error_return (0, "dpdk_interface_rx_mode_change err %d", rv);
+  return 0;
+}
+
 /* *INDENT-OFF* */
 VNET_DEVICE_CLASS (dpdk_device_class) = {
   .name = "dpdk",
@@ -711,6 +738,7 @@ VNET_DEVICE_CLASS (dpdk_device_class) = {
   .format_flow = format_dpdk_flow,
   .flow_ops_function = dpdk_flow_ops_fn,
   .set_rss_queues_function = dpdk_interface_set_rss_queues,
+  .rx_mode_change_function = dpdk_interface_rx_mode_change,
 };
 /* *INDENT-ON* */