intel_pmu: add metadata with information about scaling
authorPshyk, SerhiyX <serhiyx.pshyk@intel.com>
Mon, 7 Aug 2017 13:33:01 +0000 (14:33 +0100)
committerPshyk, SerhiyX <serhiyx.pshyk@intel.com>
Mon, 7 Aug 2017 13:37:19 +0000 (14:37 +0100)
Change-Id: I259455d35aac9edef8f05310f199637f3ce09491
Signed-off-by: Serhiy Pshyk <serhiyx.pshyk@intel.com>
src/intel_pmu.c

index e5f19ce..a964a5f 100644 (file)
@@ -67,7 +67,7 @@ struct intel_pmu_ctx_s {
   _Bool hw_cache_events;
   _Bool kernel_pmu_events;
   _Bool sw_events;
-  char  event_list_fn[PATH_MAX];
+  char event_list_fn[PATH_MAX];
   char **hw_events;
   size_t hw_events_count;
   struct eventlist *event_list;
@@ -265,7 +265,8 @@ static int pmu_config(oconfig_item_t *ci) {
   return 0;
 }
 
-static void pmu_submit_counter(int cpu, char *event, counter_t value) {
+static void pmu_submit_counter(int cpu, char *event, counter_t value,
+                               meta_data_t *meta) {
   value_list_t vl = VALUE_LIST_INIT;
 
   vl.values = &(value_t){.counter = value};
@@ -275,6 +276,7 @@ static void pmu_submit_counter(int cpu, char *event, counter_t value) {
   if (cpu == -1) {
     snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "all");
   } else {
+    vl.meta = meta;
     snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%d", cpu);
   }
   sstrncpy(vl.type, "counter", sizeof(vl.type));
@@ -283,6 +285,27 @@ static void pmu_submit_counter(int cpu, char *event, counter_t value) {
   plugin_dispatch_values(&vl);
 }
 
+meta_data_t *pmu_event_get_meta(struct event *e, int cpu) {
+  meta_data_t *meta = NULL;
+
+  /* create meta data only if value was scaled */
+  if (e->efd[cpu].val[1] != e->efd[cpu].val[2] && e->efd[cpu].val[2]) {
+    meta = meta_data_create();
+    if (meta == NULL) {
+      ERROR(PMU_PLUGIN ": meta_data_create failed.");
+      return NULL;
+    }
+
+    meta_data_add_unsigned_int(meta, "intel_pmu:raw_count", e->efd[cpu].val[0]);
+    meta_data_add_unsigned_int(meta, "intel_pmu:time_enabled",
+                               e->efd[cpu].val[1]);
+    meta_data_add_unsigned_int(meta, "intel_pmu:time_running",
+                               e->efd[cpu].val[2]);
+  }
+
+  return meta;
+}
+
 static void pmu_dispatch_data(void) {
 
   struct event *e;
@@ -297,17 +320,30 @@ static void pmu_dispatch_data(void) {
 
       event_enabled++;
 
+      /* If there are more events than counters, the kernel uses time
+       * multiplexing. With multiplexing, at the end of the run,
+       * the counter is scaled basing on total time enabled vs time running.
+       * final_count = raw_count * time_enabled/time_running
+       */
       uint64_t value = event_scaled_value(e, i);
       all_value += value;
 
+      /* get meta data with information about scaling */
+      meta_data_t *meta = pmu_event_get_meta(e, i);
+
       /* dispatch per CPU value */
-      pmu_submit_counter(i, e->event, value);
+      pmu_submit_counter(i, e->event, value, meta);
+
+      if (meta) {
+        meta_data_destroy(meta);
+        meta = NULL;
+      }
     }
 
     if (event_enabled > 0) {
       DEBUG(PMU_PLUGIN ": %-20s %'10lu", e->event, all_value);
       /* dispatch all CPU value */
-      pmu_submit_counter(-1, e->event, all_value);
+      pmu_submit_counter(-1, e->event, all_value, NULL);
     }
   }
 }
@@ -539,7 +575,6 @@ init_error:
   sfree(g_ctx.hw_events);
   g_ctx.hw_events_count = 0;
 
-
   return ret;
 }