hs-test: cat summary file after a failed test run
[vpp.git] / src / plugins / perfmon / perfmon.c
index 799659d..e618f9b 100644 (file)
@@ -141,15 +141,19 @@ perfmon_set (vlib_main_t *vm, perfmon_bundle_t *b)
 
       vec_validate (pm->group_fds, i);
       pm->group_fds[i] = -1;
+      u8 n_events_opened = 0;
 
       for (int j = 0; j < b->n_events; j++)
        {
          int fd;
          perfmon_event_t *e = s->events + b->events[j];
+         if (!e->implemented)
+           continue;
          struct perf_event_attr pe = {
            .size = sizeof (struct perf_event_attr),
            .type = e->type_from_instance ? in->type : e->type,
            .config = e->config,
+           .config1 = e->config1,
            .exclude_kernel = e->exclude_kernel,
            .read_format =
              (PERF_FORMAT_GROUP | PERF_FORMAT_TOTAL_TIME_ENABLED |
@@ -157,6 +161,7 @@ perfmon_set (vlib_main_t *vm, perfmon_bundle_t *b)
            .disabled = 1,
          };
 
+       perf_event_open:
          log_debug ("perf_event_open pe.type=%u pe.config=0x%x pid=%d "
                     "cpu=%d group_fd=%d",
                     pe.type, pe.config, in->pid, in->cpu, pm->group_fds[i]);
@@ -165,8 +170,17 @@ perfmon_set (vlib_main_t *vm, perfmon_bundle_t *b)
 
          if (fd == -1)
            {
-             err = clib_error_return_unix (0, "perf_event_open");
-             goto error;
+             if (errno ==
+                 EOPNOTSUPP) /* 64b counters not supported on aarch64 */
+               {
+                 pe.config1 = 2; /* retry with 32b counter width */
+                 goto perf_event_open;
+               }
+             else
+               {
+                 err = clib_error_return_unix (0, "perf_event_open");
+                 goto error;
+               }
            }
 
          vec_add1 (pm->fds_to_close, fd);
@@ -178,24 +192,26 @@ perfmon_set (vlib_main_t *vm, perfmon_bundle_t *b)
            {
              perfmon_thread_runtime_t *tr;
              tr = vec_elt_at_index (pm->thread_runtimes, i);
-             tr->mmap_pages[j] =
+             tr->mmap_pages[n_events_opened] =
                mmap (0, page_size, PROT_READ, MAP_SHARED, fd, 0);
 
-             if (tr->mmap_pages[j] == MAP_FAILED)
+             if (tr->mmap_pages[n_events_opened] == MAP_FAILED)
                {
                  err = clib_error_return_unix (0, "mmap");
                  goto error;
                }
            }
+         n_events_opened++;
        }
 
-      if (is_node)
+      if (is_node && n_events_opened)
        {
          perfmon_thread_runtime_t *rt;
          rt = vec_elt_at_index (pm->thread_runtimes, i);
          rt->bundle = b;
-         rt->n_events = b->n_events;
+         rt->n_events = n_events_opened;
          rt->n_nodes = n_nodes;
+         rt->preserve_samples = b->preserve_samples;
          vec_validate_aligned (rt->node_stats, n_nodes - 1,
                                CLIB_CACHE_LINE_BYTES);
        }
@@ -238,20 +254,18 @@ perfmon_start (vlib_main_t *vm, perfmon_bundle_t *b)
     }
   if (b->active_type == PERFMON_BUNDLE_TYPE_NODE)
     {
-
-      vlib_node_function_t *funcs[PERFMON_OFFSET_TYPE_MAX];
-#define _(type, pfunc) funcs[type] = pfunc;
-
-      foreach_permon_offset_type
-#undef _
-
-       ASSERT (funcs[b->offset_type]);
+      vlib_node_function_t *dispatch_wrapper = NULL;
+      err = b->src->config_dispatch_wrapper (b, &dispatch_wrapper);
+      if (err || !dispatch_wrapper)
+       {
+         perfmon_reset (vm);
+         return err;
+       }
 
       for (int i = 0; i < vlib_get_n_threads (); i++)
        vlib_node_set_dispatch_wrapper (vlib_get_main_by_index (i),
-                                       funcs[b->offset_type]);
+                                       dispatch_wrapper);
     }
-
   pm->sample_time = vlib_time_now (vm);
   pm->is_running = 1;
 
@@ -288,21 +302,6 @@ perfmon_stop (vlib_main_t *vm)
   return 0;
 }
 
-static_always_inline u8
-is_bundle_supported (perfmon_bundle_t *b)
-{
-  perfmon_cpu_supports_t *supports = b->cpu_supports;
-
-  if (!b->cpu_supports)
-    return 1;
-
-  for (int i = 0; i < b->n_cpu_supports; ++i)
-    if (supports[i].cpu_supports ())
-      return 1;
-
-  return 0;
-}
-
 static clib_error_t *
 perfmon_init (vlib_main_t *vm)
 {
@@ -326,7 +325,7 @@ perfmon_init (vlib_main_t *vm)
        }
 
       hash_set_mem (pm->source_by_name, s->name, s);
-      log_debug ("source '%s' regisrtered", s->name);
+      log_debug ("source '%s' registered", s->name);
       s = s->next;
     }
 
@@ -336,25 +335,22 @@ perfmon_init (vlib_main_t *vm)
       clib_error_t *err;
       uword *p;
 
-      if (!is_bundle_supported (b))
+      if ((p = hash_get_mem (pm->source_by_name, b->source)) == 0)
        {
-         log_warn ("skipping bundle '%s' - not supported", b->name);
+         log_debug ("missing source '%s', skipping bundle '%s'", b->source,
+                    b->name);
          b = b->next;
          continue;
        }
 
-      if (hash_get_mem (pm->bundle_by_name, b->name) != 0)
-       clib_panic ("duplicate bundle name '%s'", b->name);
-
-      if ((p = hash_get_mem (pm->source_by_name, b->source)) == 0)
+      b->src = (perfmon_source_t *) p[0];
+      if (b->src->bundle_support && !b->src->bundle_support (b))
        {
-         log_debug ("missing source '%s', skipping bundle '%s'", b->source,
-                    b->name);
+         log_debug ("skipping bundle '%s' - not supported", b->name);
          b = b->next;
          continue;
        }
 
-      b->src = (perfmon_source_t *) p[0];
       if (b->init_fn && ((err = (b->init_fn) (vm, b))))
        {
          log_warn ("skipping bundle '%s' - %U", b->name, format_clib_error,
@@ -364,8 +360,11 @@ perfmon_init (vlib_main_t *vm)
          continue;
        }
 
+      if (hash_get_mem (pm->bundle_by_name, b->name) != 0)
+       clib_panic ("duplicate bundle name '%s'", b->name);
+
       hash_set_mem (pm->bundle_by_name, b->name, b);
-      log_debug ("bundle '%s' regisrtered", b->name);
+      log_debug ("bundle '%s' registered", b->name);
 
       b = b->next;
     }