make per-adj counters configurable 45/5645/3
authorNeale Ranns <nranns@cisco.com>
Tue, 21 Feb 2017 13:33:14 +0000 (05:33 -0800)
committerDamjan Marion <dmarion.lists@gmail.com>
Tue, 7 Mar 2017 12:11:39 +0000 (12:11 +0000)
Change-Id: Ifdd2b204ecf7d855f1269c11224b9c825311904d
Signed-off-by: Neale Ranns <nranns@cisco.com>
src/vnet/adj/adj.c
src/vnet/adj/adj.h
src/vnet/ip/ip4_forward.c
src/vnet/ip/ip6_forward.c

index 11f1680..4ed4999 100644 (file)
@@ -35,6 +35,12 @@ vlib_combined_counter_main_t adjacency_counters;
  */
 ip_adjacency_t *adj_pool;
 
+/**
+ * @brief Global Config for enabling per-adjacency counters.
+ * By default these are disabled.
+ */
+int adj_per_adj_counters;
+
 always_inline void
 adj_poison (ip_adjacency_t * adj)
 {
@@ -375,11 +381,16 @@ adj_show (vlib_main_t * vm,
 {
     adj_index_t ai = ADJ_INDEX_INVALID;
     u32 sw_if_index = ~0;
+    int summary = 0;
 
     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
        if (unformat (input, "%d", &ai))
            ;
+       else if (unformat (input, "sum"))
+           summary = 1;
+       else if (unformat (input, "summary"))
+           summary = 1;
        else if (unformat (input, "%U",
                           unformat_vnet_sw_interface, vnet_get_main(),
                           &sw_if_index))
@@ -388,39 +399,49 @@ adj_show (vlib_main_t * vm,
            break;
     }
 
-    if (ADJ_INDEX_INVALID != ai)
+    if (summary)
     {
-        if (pool_is_free_index(adj_pool, ai))
-        {
-           vlib_cli_output (vm, "adjacency %d invalid", ai);
-            return 0;
-        }
-
-       vlib_cli_output (vm, "[@%d] %U",
-                         ai,
-                         format_ip_adjacency,  ai,
-                        FORMAT_IP_ADJACENCY_DETAIL);
+        vlib_cli_output (vm, "Number of adjacenies: %d", pool_elts(adj_pool));
+        vlib_cli_output (vm, "Per-adjacency counters: %s",
+                         (adj_are_counters_enabled() ?
+                          "enabled":
+                          "disabled"));
     }
     else
     {
-       /* *INDENT-OFF* */
-       pool_foreach_index(ai, adj_pool,
-       ({
-           if (~0 != sw_if_index &&
-               sw_if_index != adj_get_sw_if_index(ai))
-           {
-            }
-            else
+        if (ADJ_INDEX_INVALID != ai)
+        {
+            if (pool_is_free_index(adj_pool, ai))
             {
-               vlib_cli_output (vm, "[@%d] %U",
-                                ai,
-                                format_ip_adjacency, ai,
-                                FORMAT_IP_ADJACENCY_NONE);
-           }
-       }));
-       /* *INDENT-ON* */
-    }
+                vlib_cli_output (vm, "adjacency %d invalid", ai);
+                return 0;
+            }
 
+            vlib_cli_output (vm, "[@%d] %U",
+                             ai,
+                             format_ip_adjacency,  ai,
+                             FORMAT_IP_ADJACENCY_DETAIL);
+        }
+        else
+        {
+            /* *INDENT-OFF* */
+            pool_foreach_index(ai, adj_pool,
+            ({
+                if (~0 != sw_if_index &&
+                    sw_if_index != adj_get_sw_if_index(ai))
+                {
+                }
+                else
+                {
+                    vlib_cli_output (vm, "[@%d] %U",
+                                     ai,
+                                     format_ip_adjacency, ai,
+                                     FORMAT_IP_ADJACENCY_NONE);
+                }
+            }));
+            /* *INDENT-ON* */
+        }
+    }
     return 0;
 }
 
@@ -438,6 +459,50 @@ adj_show (vlib_main_t * vm,
  ?*/
 VLIB_CLI_COMMAND (adj_show_command, static) = {
     .path = "show adj",
-    .short_help = "show adj [<adj_index>] [interface]",
+    .short_help = "show adj [<adj_index>] [interface] [summary]",
     .function = adj_show,
 };
+
+/**
+ * @brief CLI invoked function to enable/disable per-adj counters
+ */
+static clib_error_t *
+adj_cli_counters_set (vlib_main_t * vm,
+                      unformat_input_t * input,
+                      vlib_cli_command_t * cmd)
+{
+    clib_error_t *error = NULL;
+    int enable = ~0;
+
+    while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+       if (unformat (input, "enable"))
+           enable = 1;
+       else if (unformat (input, "disable"))
+           enable = 0;
+       else
+           break;
+    }
+
+    if (enable != ~0)
+    {
+        /* user requested something sensible */
+        adj_per_adj_counters = enable;
+    }
+    else
+    {
+        error = clib_error_return (0, "specify 'enable' or 'disable'");
+    }
+
+    return (error);
+}
+
+/*?
+ * Enabe/disble per-adjacency counters. This is optional because it comes with
+ * a non-negligible performance cost.
+ ?*/
+VLIB_CLI_COMMAND (adj_cli_counters_set_command, static) = {
+    .path = "adjacency counters",
+    .short_help = "adjacency counters [enable|disable]",
+    .function = adj_cli_counters_set,
+};
index 29bae67..fcc5890 100644 (file)
@@ -108,6 +108,12 @@ extern ip_adjacency_t *adj_pool;
  */
 extern vlib_combined_counter_main_t adjacency_counters;
 
+/**
+ * @brief Global Config for enabling per-adjacency counters
+ * This is configurable because it comes with  a non-negligible
+ * performance cost. */
+extern int adj_per_adj_counters;
+
 /**
  * @brief
  * Get a pointer to an adjacency object from its index
@@ -118,4 +124,13 @@ adj_get (adj_index_t adj_index)
     return (vec_elt_at_index(adj_pool, adj_index));
 }
 
+/**
+ * @brief Get the global configuration option for enabling per-adj counters
+ */
+static inline int 
+adj_are_counters_enabled (void)
+{
+    return (adj_per_adj_counters);
+}
+
 #endif
index b3721e6..31b687d 100644 (file)
@@ -2326,7 +2326,8 @@ typedef enum
 always_inline uword
 ip4_rewrite_inline (vlib_main_t * vm,
                    vlib_node_runtime_t * node,
-                   vlib_frame_t * frame, int is_midchain, int is_mcast)
+                   vlib_frame_t * frame,
+                   int do_counters, int is_midchain, int is_mcast)
 {
   ip_lookup_main_t *lm = &ip4_main.lookup_main;
   u32 *from = vlib_frame_vector_args (frame);
@@ -2487,10 +2488,13 @@ ip4_rewrite_inline (vlib_main_t * vm,
          /*
           * pre-fetch the per-adjacency counters
           */
-         vlib_prefetch_combined_counter (&adjacency_counters,
-                                         cpu_index, adj_index0);
-         vlib_prefetch_combined_counter (&adjacency_counters,
-                                         cpu_index, adj_index1);
+         if (do_counters)
+           {
+             vlib_prefetch_combined_counter (&adjacency_counters,
+                                             cpu_index, adj_index0);
+             vlib_prefetch_combined_counter (&adjacency_counters,
+                                             cpu_index, adj_index1);
+           }
 
          /* Don't adjust the buffer for ttl issue; icmp-error node wants
           * to see the IP headerr */
@@ -2525,15 +2529,20 @@ ip4_rewrite_inline (vlib_main_t * vm,
          /*
           * Bump the per-adjacency counters
           */
-         vlib_increment_combined_counter
-           (&adjacency_counters,
-            cpu_index,
-            adj_index0, 1, vlib_buffer_length_in_chain (vm, p0) + rw_len0);
-
-         vlib_increment_combined_counter
-           (&adjacency_counters,
-            cpu_index,
-            adj_index1, 1, vlib_buffer_length_in_chain (vm, p1) + rw_len1);
+         if (do_counters)
+           {
+             vlib_increment_combined_counter
+               (&adjacency_counters,
+                cpu_index,
+                adj_index0, 1,
+                vlib_buffer_length_in_chain (vm, p0) + rw_len0);
+
+             vlib_increment_combined_counter
+               (&adjacency_counters,
+                cpu_index,
+                adj_index1, 1,
+                vlib_buffer_length_in_chain (vm, p1) + rw_len1);
+           }
 
          if (is_midchain)
            {
@@ -2722,21 +2731,30 @@ static uword
 ip4_rewrite (vlib_main_t * vm,
             vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip4_rewrite_inline (vm, node, frame, 0, 0);
+  if (adj_are_counters_enabled ())
+    return ip4_rewrite_inline (vm, node, frame, 1, 0, 0);
+  else
+    return ip4_rewrite_inline (vm, node, frame, 0, 0, 0);
 }
 
 static uword
 ip4_midchain (vlib_main_t * vm,
              vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip4_rewrite_inline (vm, node, frame, 1, 0);
+  if (adj_are_counters_enabled ())
+    return ip4_rewrite_inline (vm, node, frame, 1, 1, 0);
+  else
+    return ip4_rewrite_inline (vm, node, frame, 0, 1, 0);
 }
 
 static uword
 ip4_rewrite_mcast (vlib_main_t * vm,
                   vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip4_rewrite_inline (vm, node, frame, 0, 1);
+  if (adj_are_counters_enabled ())
+    return ip4_rewrite_inline (vm, node, frame, 1, 0, 1);
+  else
+    return ip4_rewrite_inline (vm, node, frame, 0, 0, 1);
 }
 
 /* *INDENT-OFF* */
index 066ee54..91a303d 100644 (file)
@@ -1911,7 +1911,8 @@ typedef enum
 always_inline uword
 ip6_rewrite_inline (vlib_main_t * vm,
                    vlib_node_runtime_t * node,
-                   vlib_frame_t * frame, int is_midchain, int is_mcast)
+                   vlib_frame_t * frame,
+                   int do_counters, int is_midchain, int is_mcast)
 {
   ip_lookup_main_t *lm = &ip6_main.lookup_main;
   u32 *from = vlib_frame_vector_args (frame);
@@ -2042,14 +2043,17 @@ ip6_rewrite_inline (vlib_main_t * vm,
          vnet_buffer (p0)->ip.save_rewrite_length = rw_len0;
          vnet_buffer (p1)->ip.save_rewrite_length = rw_len1;
 
-         vlib_increment_combined_counter
-           (&adjacency_counters,
-            cpu_index,
-            adj_index0, 1, vlib_buffer_length_in_chain (vm, p0) + rw_len0);
-         vlib_increment_combined_counter
-           (&adjacency_counters,
-            cpu_index, adj_index1,
-            1, vlib_buffer_length_in_chain (vm, p1) + rw_len1);
+         if (do_counters)
+           {
+             vlib_increment_combined_counter
+               (&adjacency_counters,
+                cpu_index, adj_index0, 1,
+                vlib_buffer_length_in_chain (vm, p0) + rw_len0);
+             vlib_increment_combined_counter
+               (&adjacency_counters,
+                cpu_index, adj_index1, 1,
+                vlib_buffer_length_in_chain (vm, p1) + rw_len1);
+           }
 
          /* Check MTU of outgoing interface. */
          error0 =
@@ -2175,10 +2179,13 @@ ip6_rewrite_inline (vlib_main_t * vm,
          rw_len0 = adj0[0].rewrite_header.data_bytes;
          vnet_buffer (p0)->ip.save_rewrite_length = rw_len0;
 
-         vlib_increment_combined_counter
-           (&adjacency_counters,
-            cpu_index,
-            adj_index0, 1, vlib_buffer_length_in_chain (vm, p0) + rw_len0);
+         if (do_counters)
+           {
+             vlib_increment_combined_counter
+               (&adjacency_counters,
+                cpu_index, adj_index0, 1,
+                vlib_buffer_length_in_chain (vm, p0) + rw_len0);
+           }
 
          /* Check MTU of outgoing interface. */
          error0 =
@@ -2238,21 +2245,30 @@ static uword
 ip6_rewrite (vlib_main_t * vm,
             vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip6_rewrite_inline (vm, node, frame, 0, 0);
+  if (adj_are_counters_enabled ())
+    return ip6_rewrite_inline (vm, node, frame, 1, 0, 0);
+  else
+    return ip6_rewrite_inline (vm, node, frame, 0, 0, 0);
 }
 
 static uword
 ip6_rewrite_mcast (vlib_main_t * vm,
                   vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip6_rewrite_inline (vm, node, frame, 0, 1);
+  if (adj_are_counters_enabled ())
+    return ip6_rewrite_inline (vm, node, frame, 1, 0, 1);
+  else
+    return ip6_rewrite_inline (vm, node, frame, 0, 0, 1);
 }
 
 static uword
 ip6_midchain (vlib_main_t * vm,
              vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip6_rewrite_inline (vm, node, frame, 1, 0);
+  if (adj_are_counters_enabled ())
+    return ip6_rewrite_inline (vm, node, frame, 1, 1, 0);
+  else
+    return ip6_rewrite_inline (vm, node, frame, 0, 1, 0);
 }
 
 /* *INDENT-OFF* */