Merge remote-tracking branch 'github/pr/2964'
authorFlorian Forster <octo@collectd.org>
Tue, 23 Oct 2018 06:46:51 +0000 (08:46 +0200)
committerFlorian Forster <octo@collectd.org>
Tue, 23 Oct 2018 06:46:51 +0000 (08:46 +0200)
src/collectd.conf.pod
src/cpufreq.c
src/gmond.c
src/msr-index.h
src/network.c
src/ovs_stats.c
src/pinba.c
src/statsd.c
src/turbostat.c
src/types.db
src/write_prometheus.c

index e11e514..6f5ee7f 100644 (file)
@@ -1662,6 +1662,10 @@ installed) to get the current CPU frequency. If this file does not exist make
 sure B<cpufreqd> (L<http://cpufreqd.sourceforge.net/>) or a similar tool is
 installed and an "cpu governor" (that's a kernel module) is loaded.
 
+If the system has the I<cpufreq-stats> kernel module loaded, this plugin reports
+the rate of p-state (cpu frequency) transitions and the percentage of time spent
+in each p-state.
+
 =head2 Plugin C<cpusleep>
 
 This plugin doesn't have any options. It reads CLOCK_BOOTTIME and
index 851aad4..3e3244c 100644 (file)
 #include "common.h"
 #include "plugin.h"
 
+#define MAX_AVAIL_FREQS 20
+
 static int num_cpu;
 
+struct cpu_data_t {
+  value_to_rate_state_t time_state[MAX_AVAIL_FREQS];
+} * cpu_data;
+
+/* Flags denoting capability of reporting CPU frequency statistics. */
+static bool report_p_stats = false;
+
+static void cpufreq_stats_init(void) {
+  cpu_data = calloc(num_cpu, sizeof(struct cpu_data_t));
+  if (cpu_data == NULL)
+    return;
+
+  report_p_stats = true;
+
+  /* Check for stats module and disable if not present. */
+  for (int i = 0; i < num_cpu; i++) {
+    char filename[PATH_MAX];
+
+    snprintf(filename, sizeof(filename),
+             "/sys/devices/system/cpu/cpu%d/cpufreq/stats/time_in_state", i);
+    if (access(filename, R_OK)) {
+      NOTICE("cpufreq plugin: File %s not exists or no access. P-State "
+             "statistics will not be reported. Check if `cpufreq-stats' kernel "
+             "module is loaded.",
+             filename);
+      report_p_stats = false;
+      break;
+    }
+
+    snprintf(filename, sizeof(filename),
+             "/sys/devices/system/cpu/cpu%d/cpufreq/stats/total_trans", i);
+    if (access(filename, R_OK)) {
+      NOTICE("cpufreq plugin: File %s not exists or no access. P-State "
+             "statistics will not be reported. Check if `cpufreq-stats' kernel "
+             "module is loaded.",
+             filename);
+      report_p_stats = false;
+      break;
+    }
+  }
+  return;
+}
+
 static int cpufreq_init(void) {
-  int status;
-  char filename[256];
+  char filename[PATH_MAX];
 
   num_cpu = 0;
 
   while (1) {
-    status = snprintf(filename, sizeof(filename),
-                      "/sys/devices/system/cpu/cpu%d/cpufreq/"
-                      "scaling_cur_freq",
-                      num_cpu);
+    int status = snprintf(filename, sizeof(filename),
+                          "/sys/devices/system/cpu/cpu%d/cpufreq/"
+                          "scaling_cur_freq",
+                          num_cpu);
     if ((status < 1) || ((unsigned int)status >= sizeof(filename)))
       break;
 
@@ -48,6 +92,7 @@ static int cpufreq_init(void) {
   }
 
   INFO("cpufreq plugin: Found %d CPU%s", num_cpu, (num_cpu == 1) ? "" : "s");
+  cpufreq_stats_init();
 
   if (num_cpu == 0)
     plugin_unregister_read("cpufreq");
@@ -55,23 +100,91 @@ static int cpufreq_init(void) {
   return 0;
 } /* int cpufreq_init */
 
-static void cpufreq_submit(int cpu_num, value_t value) {
+static void cpufreq_submit(int cpu_num, const char *type,
+                           const char *type_instance, value_t *value) {
   value_list_t vl = VALUE_LIST_INIT;
 
-  vl.values = &value;
+  vl.values = value;
   vl.values_len = 1;
   sstrncpy(vl.plugin, "cpufreq", sizeof(vl.plugin));
-  sstrncpy(vl.type, "cpufreq", sizeof(vl.type));
-  snprintf(vl.type_instance, sizeof(vl.type_instance), "%i", cpu_num);
+  snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", cpu_num);
+  if (type != NULL)
+    sstrncpy(vl.type, type, sizeof(vl.type));
+  if (type_instance != NULL)
+    sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
 
   plugin_dispatch_values(&vl);
 }
 
+static void cpufreq_read_stats(int cpu) {
+  char filename[PATH_MAX];
+  /* Read total transitions for cpu frequency */
+  snprintf(filename, sizeof(filename),
+           "/sys/devices/system/cpu/cpu%d/cpufreq/stats/total_trans", cpu);
+
+  value_t v;
+  if (parse_value_file(filename, &v, DS_TYPE_DERIVE) != 0) {
+    ERROR("cpufreq plugin: Reading \"%s\" failed.", filename);
+    return;
+  }
+  cpufreq_submit(cpu, "transitions", NULL, &v);
+
+  /* Determine percentage time in each state for cpu during previous
+   * interval. */
+  snprintf(filename, sizeof(filename),
+           "/sys/devices/system/cpu/cpu%d/cpufreq/stats/time_in_state", cpu);
+
+  FILE *fh = fopen(filename, "r");
+  if (fh == NULL) {
+    ERROR("cpufreq plugin: Reading \"%s\" failed.", filename);
+    return;
+  }
+
+  int state_index = 0;
+  cdtime_t now = cdtime();
+  char buffer[DATA_MAX_NAME_LEN];
+
+  while (fgets(buffer, sizeof(buffer), fh) != NULL) {
+    unsigned int frequency;
+    unsigned long long time;
+
+    /*
+     * State time units is 10ms. To get rate of seconds per second
+     * we have to divide by 100. To get percents we have to multiply it
+     * by 100 back. So, just use parsed value directly.
+     */
+    if (!sscanf(buffer, "%u%llu", &frequency, &time)) {
+      ERROR("cpufreq plugin: Reading \"%s\" failed.", filename);
+      break;
+    }
+
+    char state[DATA_MAX_NAME_LEN];
+    snprintf(state, sizeof(state), "%u", frequency);
+
+    if (state_index >= MAX_AVAIL_FREQS) {
+      NOTICE("cpufreq plugin: Found too many frequency states (%d > %d). "
+             "Plugin needs to be recompiled. Please open a bug report for "
+             "this.",
+             (state_index + 1), MAX_AVAIL_FREQS);
+      break;
+    }
+
+    gauge_t g;
+    if (value_to_rate(&g, (value_t){.derive = time}, DS_TYPE_DERIVE, now,
+                      &(cpu_data[cpu].time_state[state_index])) == 0) {
+      cpufreq_submit(cpu, "percent", state, &(value_t){.gauge = g});
+    }
+    state_index++;
+  }
+  fclose(fh);
+}
+
 static int cpufreq_read(void) {
-  for (int i = 0; i < num_cpu; i++) {
+  for (int cpu = 0; cpu < num_cpu; cpu++) {
     char filename[PATH_MAX];
+    /* Read cpu frequency */
     snprintf(filename, sizeof(filename),
-             "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", i);
+             "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", cpu);
 
     value_t v;
     if (parse_value_file(filename, &v, DS_TYPE_GAUGE) != 0) {
@@ -82,9 +195,11 @@ static int cpufreq_read(void) {
     /* convert kHz to Hz */
     v.gauge *= 1000.0;
 
-    cpufreq_submit(i, v);
-  }
+    cpufreq_submit(cpu, "cpufreq", NULL, &v);
 
+    if (report_p_stats)
+      cpufreq_read_stats(cpu);
+  }
   return 0;
 } /* int cpufreq_read */
 
index 2bca05a..291dfad 100644 (file)
@@ -252,10 +252,8 @@ static int create_sockets(socket_entry_t **ret_sockets, /* {{{ */
       sockets_num++;
       break;
     } else {
-      int yes = 1;
-
       status = setsockopt(sockets[sockets_num].fd, SOL_SOCKET, SO_REUSEADDR,
-                          (void *)&yes, sizeof(yes));
+                          &(int){1}, sizeof(int));
       if (status != 0) {
         WARNING("gmond plugin: setsockopt(2) failed: %s", STRERRNO);
       }
index 2adca57..d56a3b3 100644 (file)
 /* Intel MSRs. Some also available on other CPUs */
 
 /* C-state Residency Counters */
-#define MSR_PKG_C3_RESIDENCY           0x000003f8
-#define MSR_PKG_C6_RESIDENCY           0x000003f9
-#define MSR_ATOM_PKG_C6_RESIDENCY      0x000003fa
-#define MSR_PKG_C7_RESIDENCY           0x000003fa
-#define MSR_CORE_C3_RESIDENCY          0x000003fc
-#define MSR_CORE_C6_RESIDENCY          0x000003fd
-#define MSR_CORE_C7_RESIDENCY          0x000003fe
-#define MSR_KNL_CORE_C6_RESIDENCY      0x000003ff
-#define MSR_PKG_C2_RESIDENCY           0x0000060d
-#define MSR_PKG_C8_RESIDENCY           0x00000630
-#define MSR_PKG_C9_RESIDENCY           0x00000631
-#define MSR_PKG_C10_RESIDENCY          0x00000632
+#define MSR_PKG_C3_RESIDENCY 0x000003f8
+#define MSR_PKG_C6_RESIDENCY 0x000003f9
+#define MSR_ATOM_PKG_C6_RESIDENCY 0x000003fa
+#define MSR_PKG_C7_RESIDENCY 0x000003fa
+#define MSR_CORE_C3_RESIDENCY 0x000003fc
+#define MSR_CORE_C6_RESIDENCY 0x000003fd
+#define MSR_CORE_C7_RESIDENCY 0x000003fe
+#define MSR_KNL_CORE_C6_RESIDENCY 0x000003ff
+#define MSR_PKG_C2_RESIDENCY 0x0000060d
+#define MSR_PKG_C8_RESIDENCY 0x00000630
+#define MSR_PKG_C9_RESIDENCY 0x00000631
+#define MSR_PKG_C10_RESIDENCY 0x00000632
 
 /* Run Time Average Power Limiting (RAPL) Interface */
 
-#define MSR_RAPL_POWER_UNIT            0x00000606
+#define MSR_RAPL_POWER_UNIT 0x00000606
 
-#define MSR_PKG_POWER_LIMIT            0x00000610
-#define MSR_PKG_ENERGY_STATUS          0x00000611
-#define MSR_PKG_PERF_STATUS            0x00000613
-#define MSR_PKG_POWER_INFO             0x00000614
+#define MSR_PKG_POWER_LIMIT 0x00000610
+#define MSR_PKG_ENERGY_STATUS 0x00000611
+#define MSR_PKG_PERF_STATUS 0x00000613
+#define MSR_PKG_POWER_INFO 0x00000614
 
-#define MSR_DRAM_POWER_LIMIT           0x00000618
-#define MSR_DRAM_ENERGY_STATUS         0x00000619
-#define MSR_DRAM_PERF_STATUS           0x0000061b
-#define MSR_DRAM_POWER_INFO            0x0000061c
-
-#define MSR_PP0_POWER_LIMIT            0x00000638
-#define MSR_PP0_ENERGY_STATUS          0x00000639
-#define MSR_PP0_POLICY                 0x0000063a
-#define MSR_PP0_PERF_STATUS            0x0000063b
-
-#define MSR_PP1_POWER_LIMIT            0x00000640
-#define MSR_PP1_ENERGY_STATUS          0x00000641
-#define MSR_PP1_POLICY                 0x00000642
+#define MSR_DRAM_POWER_LIMIT 0x00000618
+#define MSR_DRAM_ENERGY_STATUS 0x00000619
+#define MSR_UNCORE_FREQ_SCALING 0x00000621
+#define MSR_DRAM_PERF_STATUS 0x0000061b
+#define MSR_DRAM_POWER_INFO 0x0000061c
 
+#define MSR_PP0_POWER_LIMIT 0x00000638
+#define MSR_PP0_ENERGY_STATUS 0x00000639
+#define MSR_PP0_POLICY 0x0000063a
+#define MSR_PP0_PERF_STATUS 0x0000063b
 
+#define MSR_PP1_POWER_LIMIT 0x00000640
+#define MSR_PP1_ENERGY_STATUS 0x00000641
+#define MSR_PP1_POLICY 0x00000642
 
 /* Intel defined MSRs. */
-#define MSR_IA32_TSC                   0x00000010
-#define MSR_SMI_COUNT                  0x00000034
-
-#define MSR_IA32_MPERF                 0x000000e7
-#define MSR_IA32_APERF                 0x000000e8
+#define MSR_IA32_TSC 0x00000010
+#define MSR_SMI_COUNT 0x00000034
 
-#define MSR_IA32_THERM_STATUS          0x0000019c
+#define MSR_IA32_MPERF 0x000000e7
+#define MSR_IA32_APERF 0x000000e8
 
-#define MSR_IA32_TEMPERATURE_TARGET    0x000001a2
+#define MSR_IA32_THERM_STATUS 0x0000019c
 
-#define MSR_IA32_PACKAGE_THERM_STATUS          0x000001b1
+#define MSR_IA32_MISC_ENABLE 0x000001a0
+#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
 
+#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
 
 #endif /* _ASM_X86_MSR_INDEX_H */
index d602dfc..64c6d24 100644 (file)
@@ -1728,10 +1728,9 @@ static int network_bind_socket(int fd, const struct addrinfo *ai,
 #else
   int loop = 0;
 #endif
-  int yes = 1;
 
   /* allow multiple sockets to use the same PORT number */
-  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) {
+  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) == -1) {
     ERROR("network plugin: setsockopt (reuseaddr): %s", STRERRNO);
     return -1;
   }
index f513e72..a629ec6 100644 (file)
@@ -94,42 +94,46 @@ typedef struct bridge_list_s {
   struct bridge_list_s *next; /* Next bridge*/
 } bridge_list_t;
 
+#define cnt_str(x) [x] = #x
+
 static const char *const iface_counter_table[IFACE_COUNTER_COUNT] = {
-        [collisions] = "collisions",
-        [rx_bytes] = "rx_bytes",
-        [rx_crc_err] = "rx_crc_err",
-        [rx_dropped] = "rx_dropped",
-        [rx_errors] = "rx_errors",
-        [rx_frame_err] = "rx_frame_err",
-        [rx_over_err] = "rx_over_err",
-        [rx_packets] = "rx_packets",
-        [tx_bytes] = "tx_bytes",
-        [tx_dropped] = "tx_dropped",
-        [tx_errors] = "tx_errors",
-        [tx_packets] = "tx_packets",
-        [rx_1_to_64_packets] = "rx_1_to_64_packets",
-        [rx_65_to_127_packets] = "rx_65_to_127_packets",
-        [rx_128_to_255_packets] = "rx_128_to_255_packets",
-        [rx_256_to_511_packets] = "rx_256_to_511_packets",
-        [rx_512_to_1023_packets] = "rx_512_to_1023_packets",
-        [rx_1024_to_1522_packets] = "rx_1024_to_1518_packets",
-        [rx_1523_to_max_packets] = "rx_1523_to_max_packets",
-        [tx_1_to_64_packets] = "tx_1_to_64_packets",
-        [tx_65_to_127_packets] = "tx_65_to_127_packets",
-        [tx_128_to_255_packets] = "tx_128_to_255_packets",
-        [tx_256_to_511_packets] = "tx_256_to_511_packets",
-        [tx_512_to_1023_packets] = "tx_512_to_1023_packets",
-        [tx_1024_to_1522_packets] = "tx_1024_to_1518_packets",
-        [tx_1523_to_max_packets] = "tx_1523_to_max_packets",
-        [tx_multicast_packets] = "tx_multicast_packets",
-        [rx_broadcast_packets] = "rx_broadcast_packets",
-        [tx_broadcast_packets] = "tx_broadcast_packets",
-        [rx_undersized_errors] = "rx_undersized_errors",
-        [rx_oversize_errors] = "rx_oversize_errors",
-        [rx_fragmented_errors] = "rx_fragmented_errors",
-        [rx_jabber_errors] = "rx_jabber_errors",
+    cnt_str(collisions),
+    cnt_str(rx_bytes),
+    cnt_str(rx_crc_err),
+    cnt_str(rx_dropped),
+    cnt_str(rx_errors),
+    cnt_str(rx_frame_err),
+    cnt_str(rx_over_err),
+    cnt_str(rx_packets),
+    cnt_str(tx_bytes),
+    cnt_str(tx_dropped),
+    cnt_str(tx_errors),
+    cnt_str(tx_packets),
+    cnt_str(rx_1_to_64_packets),
+    cnt_str(rx_65_to_127_packets),
+    cnt_str(rx_128_to_255_packets),
+    cnt_str(rx_256_to_511_packets),
+    cnt_str(rx_512_to_1023_packets),
+    cnt_str(rx_1024_to_1522_packets),
+    cnt_str(rx_1523_to_max_packets),
+    cnt_str(tx_1_to_64_packets),
+    cnt_str(tx_65_to_127_packets),
+    cnt_str(tx_128_to_255_packets),
+    cnt_str(tx_256_to_511_packets),
+    cnt_str(tx_512_to_1023_packets),
+    cnt_str(tx_1024_to_1522_packets),
+    cnt_str(tx_1523_to_max_packets),
+    cnt_str(tx_multicast_packets),
+    cnt_str(rx_broadcast_packets),
+    cnt_str(tx_broadcast_packets),
+    cnt_str(rx_undersized_errors),
+    cnt_str(rx_oversize_errors),
+    cnt_str(rx_fragmented_errors),
+    cnt_str(rx_jabber_errors),
 };
 
+#undef cnt_str
+
 /* Entry into the list of network bridges */
 static bridge_list_t *g_bridge_list_head;
 
@@ -964,7 +968,7 @@ static int ovs_stats_plugin_read(__attribute__((unused)) user_data_t *ud) {
           ovs_stats_submit_two(devname, "if_packets", "512_to_1023_packets",
                                port->stats[rx_512_to_1023_packets],
                                port->stats[tx_512_to_1023_packets], meta);
-          ovs_stats_submit_two(devname, "if_packets", "1024_to_1518_packets",
+          ovs_stats_submit_two(devname, "if_packets", "1024_to_1522_packets",
                                port->stats[rx_1024_to_1522_packets],
                                port->stats[tx_1024_to_1522_packets], meta);
           ovs_stats_submit_two(devname, "if_packets", "1523_to_max_packets",
index 66b9cd1..9f571d0 100644 (file)
@@ -280,9 +280,6 @@ static int pb_del_socket(pinba_socket_t *s, /* {{{ */
 
 static int pb_add_socket(pinba_socket_t *s, /* {{{ */
                          const struct addrinfo *ai) {
-  int fd;
-  int tmp;
-  int status;
 
   if (s->fd_num == PINBA_MAX_SOCKETS) {
     WARNING("pinba plugin: Sorry, you have hit the built-in limit of "
@@ -292,14 +289,13 @@ static int pb_add_socket(pinba_socket_t *s, /* {{{ */
     return -1;
   }
 
-  fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+  int fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
   if (fd < 0) {
     ERROR("pinba plugin: socket(2) failed: %s", STRERRNO);
     return 0;
   }
 
-  tmp = 1;
-  status = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
+  int status = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));
   if (status != 0) {
     WARNING("pinba plugin: setsockopt(SO_REUSEADDR) failed: %s", STRERRNO);
   }
index 6fbfd18..1558ec8 100644 (file)
@@ -498,6 +498,14 @@ static int statsd_network_init(struct pollfd **ret_fds, /* {{{ */
       continue;
     }
 
+    /* allow multiple sockets to use the same PORT number */
+    int yes = 1;
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) {
+      ERROR("statsd plugin: setsockopt (reuseaddr): %s", STRERRNO);
+      close(fd);
+      continue;
+    }
+
     getnameinfo(ai_ptr->ai_addr, ai_ptr->ai_addrlen, str_node, sizeof(str_node),
                 str_service, sizeof(str_service),
                 NI_DGRAM | NI_NUMERICHOST | NI_NUMERICSERV);
@@ -525,6 +533,7 @@ static int statsd_network_init(struct pollfd **ret_fds, /* {{{ */
     memset(tmp, 0, sizeof(*tmp));
     tmp->fd = fd;
     tmp->events = POLLIN | POLLPRI;
+    INFO("statsd plugin: Listening on [%s]:%s.", str_node, str_service);
   }
 
   freeaddrinfo(ai_list);
index b5d3520..49c3968 100644 (file)
@@ -129,14 +129,21 @@ static bool apply_config_ptm;
  */
 static unsigned int tcc_activation_temp;
 
+static unsigned int do_power_fields;
+#define UFS_PLATFORM (1 << 0)
+#define TURBO_PLATFORM (1 << 1)
+#define PSTATES_PLATFORM (1 << 2)
+
 static unsigned int do_rapl;
 static unsigned int config_rapl;
 static bool apply_config_rapl;
 static double rapl_energy_units;
+static double rapl_power_units;
 
 #define RAPL_PKG (1 << 0)
 /* 0x610 MSR_PKG_POWER_LIMIT */
 /* 0x611 MSR_PKG_ENERGY_STATUS */
+/* 0x614 MSR_PKG_POWER_INFO */
 #define RAPL_DRAM (1 << 1)
 /* 0x618 MSR_DRAM_POWER_LIMIT */
 /* 0x619 MSR_DRAM_ENERGY_STATUS */
@@ -188,6 +195,10 @@ static struct pkg_data {
   uint32_t energy_dram;  /* MSR_DRAM_ENERGY_STATUS */
   uint32_t energy_cores; /* MSR_PP0_ENERGY_STATUS */
   uint32_t energy_gfx;   /* MSR_PP1_ENERGY_STATUS */
+  uint32_t tdp;
+  uint8_t turbo_enabled;
+  uint8_t pstates_enabled;
+  uint32_t uncore;
   unsigned int tcc_activation_temp;
   unsigned int pkg_temp_c;
 } * package_delta, *package_even, *package_odd;
@@ -395,6 +406,8 @@ get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) {
   if (do_rapl & RAPL_PKG) {
     READ_MSR(MSR_PKG_ENERGY_STATUS, &msr);
     p->energy_pkg = msr & 0xFFFFFFFF;
+    READ_MSR(MSR_PKG_POWER_INFO, &msr);
+    p->tdp = msr & 0x7FFF;
   }
   if (do_rapl & RAPL_CORES) {
     READ_MSR(MSR_PP0_ENERGY_STATUS, &msr);
@@ -412,6 +425,18 @@ get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) {
     READ_MSR(MSR_IA32_PACKAGE_THERM_STATUS, &msr);
     p->pkg_temp_c = p->tcc_activation_temp - ((msr >> 16) & 0x7F);
   }
+  if (do_power_fields & TURBO_PLATFORM) {
+    READ_MSR(MSR_IA32_MISC_ENABLE, &msr);
+    p->turbo_enabled = !((msr >> 38) & 0x1);
+  }
+  if (do_power_fields & PSTATES_PLATFORM) {
+    READ_MSR(MSR_IA32_MISC_ENABLE, &msr);
+    p->pstates_enabled = (msr >> 16) & 0x1;
+  }
+  if (do_power_fields & UFS_PLATFORM) {
+    READ_MSR(MSR_UNCORE_FREQ_SCALING, &msr);
+    p->uncore = msr & 0x1F;
+  }
 
 out:
   close(msr_fd);
@@ -442,6 +467,11 @@ static inline void delta_package(struct pkg_data *delta,
   delta->energy_cores = new->energy_cores - old->energy_cores;
   delta->energy_gfx = new->energy_gfx - old->energy_gfx;
   delta->energy_dram = new->energy_dram - old->energy_dram;
+  delta->tdp = new->tdp;
+  delta->turbo_enabled = new->turbo_enabled;
+  delta->pstates_enabled = new->pstates_enabled;
+  delta->tcc_activation_temp = new->tcc_activation_temp;
+  delta->uncore = new->uncore;
 }
 
 /*
@@ -627,9 +657,11 @@ static int submit_counters(struct thread_data *t, struct core_data *c,
     turbostat_submit(name, "percent", "pc10", 100.0 * p->pc10 / t->tsc);
 
   if (do_rapl) {
-    if (do_rapl & RAPL_PKG)
+    if (do_rapl & RAPL_PKG) {
       turbostat_submit(name, "power", "pkg",
                        p->energy_pkg * rapl_energy_units / interval_float);
+      turbostat_submit(name, "tdp", "pkg", p->tdp * rapl_power_units);
+    }
     if (do_rapl & RAPL_CORES)
       turbostat_submit(name, "power", "cores",
                        p->energy_cores * rapl_energy_units / interval_float);
@@ -640,6 +672,18 @@ static int submit_counters(struct thread_data *t, struct core_data *c,
       turbostat_submit(name, "power", "DRAM",
                        p->energy_dram * rapl_energy_units / interval_float);
   }
+
+  if (do_power_fields & TURBO_PLATFORM) {
+    turbostat_submit(name, "turbo_enabled", NULL, p->turbo_enabled);
+  }
+  if (do_power_fields & PSTATES_PLATFORM) {
+    turbostat_submit(name, "pstates_enabled", NULL, p->pstates_enabled);
+  }
+  if (do_power_fields & UFS_PLATFORM) {
+    turbostat_submit(name, "uncore_ratio", NULL, p->uncore);
+  }
+  turbostat_submit(name, "temperature", "tcc_activation",
+                   p->tcc_activation_temp);
 done:
   return 0;
 }
@@ -985,10 +1029,12 @@ static int __attribute__((warn_unused_result)) probe_cpu(void) {
     case 0x4F: /* BDX */
     case 0x56: /* BDX-DE */
       do_rapl = RAPL_PKG | RAPL_DRAM;
+      do_power_fields = TURBO_PLATFORM | UFS_PLATFORM | PSTATES_PLATFORM;
       break;
     case 0x2D: /* SNB Xeon */
     case 0x3E: /* IVB Xeon */
       do_rapl = RAPL_PKG | RAPL_CORES | RAPL_DRAM;
+      do_power_fields = TURBO_PLATFORM | PSTATES_PLATFORM;
       break;
     case 0x37: /* BYT */
     case 0x4D: /* AVN */
@@ -1023,6 +1069,7 @@ static int __attribute__((warn_unused_result)) probe_cpu(void) {
     if (get_msr(0, MSR_RAPL_POWER_UNIT, &msr))
       return 0;
 
+    rapl_power_units = 1.0 / (1 << (msr & 0xF));
     if (model == 0x37)
       rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
     else
index f4933ee..e9de64f 100644 (file)
@@ -209,6 +209,7 @@ ps_rss                  value:GAUGE:0:9223372036854775807
 ps_stacksize            value:GAUGE:0:9223372036854775807
 ps_state                value:GAUGE:0:65535
 ps_vm                   value:GAUGE:0:9223372036854775807
+pstates_enabled         value:GAUGE:0:1
 pubsub                  value:GAUGE:0:U
 queue_length            value:GAUGE:0:U
 records                 value:GAUGE:0:U
@@ -239,6 +240,7 @@ spl                     value:GAUGE:U:U
 swap                    value:GAUGE:0:1099511627776
 swap_io                 value:DERIVE:0:U
 tcp_connections         value:GAUGE:0:4294967295
+tdp                     value:GAUGE:U:U
 temperature             value:GAUGE:U:U
 threads                 value:GAUGE:0:U
 time_dispersion         value:GAUGE:-1000000:1000000
@@ -257,7 +259,10 @@ total_sessions          value:DERIVE:0:U
 total_threads           value:DERIVE:0:U
 total_time_in_ms        value:DERIVE:0:U
 total_values            value:DERIVE:0:U
+turbo_enabled           value:GAUGE:0:1
+transitions             value:DERIVE:0:U
 uptime                  value:GAUGE:0:4294967295
+uncore_ratio            value:GAUGE:0:U
 users                   value:GAUGE:0:65535
 vcl                     value:GAUGE:0:65535
 vcpu                    value:GAUGE:0:U
index 6f9b049..7137558 100644 (file)
@@ -763,8 +763,7 @@ static int prom_open_socket(int addrfamily) {
     if (fd == -1)
       continue;
 
-    int tmp = 1;
-    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)) != 0) {
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) != 0) {
       WARNING("write_prometheus: setsockopt(SO_REUSEADDR) failed: %s",
               STRERRNO);
       close(fd);