LSIP: make LISP statistics collecting thread safe, VPP-692 04/6104/3
authorFilip Tehlar <[email protected]>
Mon, 10 Apr 2017 05:54:31 +0000 (07:54 +0200)
committerFlorin Coras <[email protected]>
Tue, 11 Apr 2017 06:30:06 +0000 (06:30 +0000)
Change-Id: If884835c0f63de162ecf75fecd2a63a1240ee910
Signed-off-by: Filip Tehlar <[email protected]>
src/vnet/lisp-cp/control.c
src/vnet/lisp-cp/one_api.c
src/vnet/lisp-cp/one_cli.c
src/vnet/lisp-gpe/lisp_gpe.c
src/vnet/lisp-gpe/lisp_gpe.h
src/vnet/lisp-gpe/lisp_gpe_adjacency.c
src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c
src/vnet/lisp-gpe/lisp_gpe_fwd_entry.h

index 5c901f3..ebbd1be 100644 (file)
@@ -285,7 +285,7 @@ dp_del_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
   if (fe->is_src_dst)
     gid_address_copy (&a->lcl_eid, &fe->leid);
 
-  vnet_lisp_del_fwd_stats (a, feip[0]);
+  vnet_lisp_gpe_del_fwd_counters (a, feip[0]);
   vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
 
   /* delete entry in fwd table */
@@ -532,10 +532,18 @@ dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
       a->action = rmt_map->action;
     }
 
-  vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
+  rv = vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
+  if (rv)
+    {
+      if (a->locator_pairs)
+       vec_free (a->locator_pairs);
+      return;
+    }
 
-  /* add tunnel to fwd entry table XXX check return value from DP insertion */
+  /* add tunnel to fwd entry table */
   pool_get (lcm->fwd_entry_pool, fe);
+  vnet_lisp_gpe_add_fwd_counters (a, fe - lcm->fwd_entry_pool);
+
   fe->locator_pairs = a->locator_pairs;
   gid_address_copy (&fe->reid, &a->rmt_eid);
 
@@ -3608,7 +3616,8 @@ lisp_stats_api_fill (lisp_cp_main_t * lcm, lisp_gpe_main_t * lgm,
                     lisp_api_stats_t * stat, lisp_stats_key_t * key,
                     u32 stats_index)
 {
-  lisp_stats_t *s;
+  vlib_counter_t v;
+  vlib_combined_counter_main_t *cm = &lgm->counters;
   lisp_gpe_fwd_entry_key_t fwd_key;
   const lisp_gpe_tunnel_t *lgt;
   fwd_entry_t *fe;
@@ -3627,8 +3636,8 @@ lisp_stats_api_fill (lisp_cp_main_t * lcm, lisp_gpe_main_t * lgm,
   stat->loc_rloc = lgt->key->lcl;
   stat->rmt_rloc = lgt->key->rmt;
 
-  s = pool_elt_at_index (lgm->lisp_stats_pool, stats_index);
-  stat->stats = *s;
+  vlib_get_combined_counter (cm, stats_index, &v);
+  stat->counters = v;
   return 1;
 }
 
index ab9e7a6..9a07908 100644 (file)
@@ -1366,8 +1366,8 @@ vl_api_one_stats_dump_t_handler (vl_api_one_stats_dump_t * mp)
         ip_address_copy_addr (rmp->rloc, &stat->rmt_rloc);
         ip_address_copy_addr (rmp->lloc, &stat->loc_rloc);
 
-        rmp->pkt_count = clib_host_to_net_u32 (stat->stats.pkt_count);
-        rmp->bytes = clib_host_to_net_u32 (stat->stats.bytes);
+        rmp->pkt_count = clib_host_to_net_u32 (stat->counters.packets);
+        rmp->bytes = clib_host_to_net_u32 (stat->counters.bytes);
       }));
       /* *INDENT-ON* */
   }
index b5bc529..40f70e3 100644 (file)
@@ -1678,7 +1678,7 @@ lisp_show_stats_details_command_fn (vlib_main_t * vm,
                     format_fid_address, &stat->deid,
                     format_ip_address, &stat->loc_rloc,
                     format_ip_address, &stat->rmt_rloc,
-                    stat->stats.pkt_count, stat->stats.bytes);
+                    stat->counters.packets, stat->counters.bytes);
   }
   vec_free (stats);
   return 0;
index 1241ab9..052410e 100644 (file)
@@ -426,6 +426,9 @@ lisp_gpe_init (vlib_main_t * vm)
 
   lgm->lisp_stats_index_by_key =
     hash_create_mem (0, sizeof (lisp_stats_key_t), sizeof (uword));
+  memset (&lgm->counters, 0, sizeof (lgm->counters));
+  lgm->counters.name = "LISP counters";
+
   return 0;
 }
 
index b3821ac..b445dcf 100644 (file)
@@ -96,12 +96,6 @@ typedef struct
   u32 tunnel_index;
 } lisp_stats_key_t;
 
-typedef struct
-{
-  u32 pkt_count;
-  u32 bytes;
-} lisp_stats_t;
-
 typedef struct
 {
   u32 vni;
@@ -110,7 +104,7 @@ typedef struct
   ip_address_t loc_rloc;
   ip_address_t rmt_rloc;
 
-  lisp_stats_t stats;
+  vlib_counter_t counters;
 } lisp_api_stats_t;
 
 typedef enum gpe_encap_mode_e
@@ -165,8 +159,9 @@ typedef struct lisp_gpe_main
 
   gpe_encap_mode_t encap_mode;
 
-  lisp_stats_t *lisp_stats_pool;
+  lisp_stats_key_t *stats_key_pool;
   uword *lisp_stats_index_by_key;
+  vlib_combined_counter_main_t counters;
 
   /** convenience */
   vlib_main_t *vlib_main;
@@ -313,7 +308,7 @@ int vnet_gpe_set_encap_mode (gpe_encap_mode_t mode);
 u8 vnet_lisp_stats_enable_disable_state (void);
 vnet_api_error_t vnet_lisp_stats_enable_disable (u8 enable);
 lisp_api_stats_t *vnet_lisp_get_stats (void);
-void vnet_lisp_flush_stats (void);
+int vnet_lisp_flush_stats (void);
 
 #endif /* included_vnet_lisp_gpe_h */
 
index 50662dd..6cb323c 100644 (file)
@@ -250,7 +250,6 @@ lisp_gpe_increment_stats_counters (lisp_cp_main_t * lcm, ip_adjacency_t * adj,
   index_t lai;
   u32 si, di;
   gid_address_t src, dst;
-  lisp_stats_t *stats;
   uword *feip;
 
   ip46_address_to_ip_address (&adj->sub_type.nbr.next_hop, &rloc);
@@ -299,23 +298,12 @@ lisp_gpe_increment_stats_counters (lisp_cp_main_t * lcm, ip_adjacency_t * adj,
   key.tunnel_index = ladj->tunnel_index;
 
   uword *p = hash_get_mem (lgm->lisp_stats_index_by_key, &key);
-  if (p)
-    {
-      stats = pool_elt_at_index (lgm->lisp_stats_pool, p[0]);
-    }
-  else
-    {
-      pool_get (lgm->lisp_stats_pool, stats);
-      memset (stats, 0, sizeof (*stats));
+  ASSERT (p);
 
-      lisp_stats_key_t *key_copy = clib_mem_alloc (sizeof (*key_copy));
-      memcpy (key_copy, &key, sizeof (*key_copy));
-      hash_set_mem (lgm->lisp_stats_index_by_key, key_copy,
-                   stats - lgm->lisp_stats_pool);
-    }
-  stats->pkt_count++;
   /* compute payload length starting after GPE */
-  stats->bytes += b->current_length - (lisp_data - b->data - b->current_data);
+  u32 bytes = b->current_length - (lisp_data - b->data - b->current_data);
+  vlib_increment_combined_counter (&lgm->counters, os_get_cpu_number (),
+                                  p[0], 1, bytes);
 }
 
 static void
index efa724e..8b4fbbf 100644 (file)
@@ -409,6 +409,42 @@ lisp_gpe_fwd_entry_mk_paths (lisp_gpe_fwd_entry_t * lfe,
   vec_sort_with_function (lfe->paths, lisp_gpe_fwd_entry_path_sort);
 }
 
+void
+vnet_lisp_gpe_add_fwd_counters (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
+                               u32 fwd_entry_index)
+{
+  const lisp_gpe_adjacency_t *ladj;
+  lisp_fwd_path_t *path;
+  lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
+  lisp_gpe_fwd_entry_t *lfe;
+  lisp_gpe_fwd_entry_key_t fe_key;
+  lisp_stats_key_t key, *stats_key;
+
+  lfe = find_fwd_entry (lgm, a, &fe_key);
+
+  if (LISP_GPE_FWD_ENTRY_TYPE_NORMAL != lfe->type)
+    return;
+
+  memset (&key, 0, sizeof (key));
+  key.fwd_entry_index = fwd_entry_index;
+
+  vec_foreach (path, lfe->paths)
+  {
+    ladj = lisp_gpe_adjacency_get (path->lisp_adj);
+    key.tunnel_index = ladj->tunnel_index;
+
+    pool_get (lgm->stats_key_pool, stats_key);
+    memcpy (stats_key, &key, sizeof (key));
+    hash_set_mem (lgm->lisp_stats_index_by_key, stats_key,
+                 stats_key - lgm->stats_key_pool);
+
+    vlib_validate_combined_counter (&lgm->counters,
+                                   stats_key - lgm->stats_key_pool);
+    vlib_zero_combined_counter (&lgm->counters,
+                               stats_key - lgm->stats_key_pool);
+  }
+}
+
 /**
  * @brief Add/Delete LISP IP forwarding entry.
  *
@@ -1171,49 +1207,39 @@ vnet_lisp_gpe_add_del_fwd_entry (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
     }
 }
 
-void
+int
 vnet_lisp_flush_stats (void)
 {
   lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
-  lisp_stats_t *stat;
+  vlib_combined_counter_main_t *cm = &lgm->counters;
+  u32 i;
 
-  /* *INDENT-OFF* */
-  pool_foreach (stat, lgm->lisp_stats_pool,
-  {
-    stat->pkt_count = 0;
-    stat->bytes = 0;
-  });
-  /* *INDENT-ON* */
+  for (i = 0; i < vlib_combined_counter_n_counters (cm); i++)
+    vlib_zero_combined_counter (cm, i);
+
+  return 0;
 }
 
 static void
 lisp_del_adj_stats (lisp_gpe_main_t * lgm, u32 fwd_entry_index, u32 ti)
 {
-  hash_pair_t *hp;
   lisp_stats_key_t key;
-  void *key_copy;
   uword *p;
-  lisp_stats_t *s;
 
   memset (&key, 0, sizeof (key));
   key.fwd_entry_index = fwd_entry_index;
   key.tunnel_index = ti;
 
   p = hash_get_mem (lgm->lisp_stats_index_by_key, &key);
-  if (p)
-    {
-      s = pool_elt_at_index (lgm->lisp_stats_pool, p[0]);
-      hp = hash_get_pair (lgm->lisp_stats_index_by_key, &key);
-      key_copy = (void *) (hp->key);
-      hash_unset_mem (lgm->lisp_stats_index_by_key, &key);
-      clib_mem_free (key_copy);
-      pool_put (lgm->lisp_stats_pool, s);
-    }
+  ASSERT (p);
+
+  pool_put_index (lgm->stats_key_pool, p[0]);
+  hash_unset_mem (lgm->lisp_stats_index_by_key, &key);
 }
 
 void
-vnet_lisp_del_fwd_stats (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
-                        u32 fwd_entry_index)
+vnet_lisp_gpe_del_fwd_counters (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
+                               u32 fwd_entry_index)
 {
   lisp_gpe_main_t *lgm = &lisp_gpe_main;
   lisp_gpe_fwd_entry_key_t fe_key;
index 92e1852..b9d9c98 100644 (file)
@@ -212,8 +212,11 @@ extern u32 lisp_l2_fib_lookup (lisp_gpe_main_t * lgm,
 extern const dpo_id_t *lisp_nsh_fib_lookup (lisp_gpe_main_t * lgm,
                                            u32 spi_si);
 extern void
-vnet_lisp_del_fwd_stats (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
-                        u32 fwd_entry_index);
+vnet_lisp_gpe_del_fwd_counters (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
+                               u32 fwd_entry_index);
+extern void
+vnet_lisp_gpe_add_fwd_counters (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
+                               u32 fwd_entry_index);
 #endif
 
 /*